diff --git a/docs/components/balloon.ejs b/docs/components/balloon.ejs
index 9180f0b..18ecf8f 100644
--- a/docs/components/balloon.ejs
+++ b/docs/components/balloon.ejs
@@ -20,6 +20,25 @@
You will need to set up an event for the control to trigger the balloon.
- <%- example(`Press Backspace to dismiss
`) %>
+ <%- example(`
+
+ Press Backspace to dismiss
+ `) %>
+
+
+ To change the position of the balloon, which subsequently change the placement of its tail, combine
+ the respective vertical and horizontal classes:
+
+ Vertical: .is-top / .is-bottom
+ Horizontal: .is-left / .is-right
+
+
+ <%- example(`
+ This balloon is positioned bottom right of the source control (default behavior).
+ This balloon is positioned bottom left of the source control.
+ This balloon is positioned top left of the source control.
+ This balloon is positioned top right of the source control.
+ `) %>
+
\ No newline at end of file
diff --git a/docs/components/searchbox.ejs b/docs/components/searchbox.ejs
new file mode 100644
index 0000000..daccae5
--- /dev/null
+++ b/docs/components/searchbox.ejs
@@ -0,0 +1,34 @@
+
+ SearchBox
+
+
+ With a Search box , users can quickly locate specific objects or text within a large set of data by
+ filtering or highlighting matches.
+
+
+
+
+
+ There are 2 variants of the search box available.
+
+
+
+ An instant search , where the results are displayed immediately as the user types, can be rendered
+ just by specifying a type="search" attribute on an input element:
+
+
+ <%- example(`
`) %>
+
+
+ A regular search , where a search is performed when the user clicks the search button, requires
+ a search input and a button wrapped inside a container a container element with the class searchbox.
+
+
+ <%- example(`
+
+
+
+
`) %>
+
+
\ No newline at end of file
diff --git a/docs/docs.css b/docs/docs.css
index 044e36a..e7faae2 100644
--- a/docs/docs.css
+++ b/docs/docs.css
@@ -142,6 +142,10 @@ blockquote footer {
width: 450px;
}
+[role="tooltip"]:not([id]) {
+ margin: 2em 0;
+}
+
@media (max-width: 480px) {
aside {
display: none;
diff --git a/docs/index.html.ejs b/docs/index.html.ejs
index 443d856..4a532f0 100644
--- a/docs/index.html.ejs
+++ b/docs/index.html.ejs
@@ -79,6 +79,7 @@
<%- include('components/optionbutton') -%>
<%- include('components/progressbar') -%>
<%- include('components/scrollbar') -%>
+ <%- include('components/searchbox') -%>
<%- include('components/slider') -%>
<%- include('components/spinner') -%>
<%- include('components/tabs') -%>
diff --git a/docs/script.js b/docs/script.js
index 53fae37..a7c5ea7 100644
--- a/docs/script.js
+++ b/docs/script.js
@@ -40,6 +40,7 @@ document
if (e.key === "Enter") {
tooltip.removeAttribute("hidden");
tooltip.style.top = input.offsetTop + input.offsetHeight + 15 + "px";
+ tooltip.style.zIndex = 1;
}
if (e.key === "Backspace") {
tooltip.setAttribute("hidden", true);
diff --git a/docs/sections/navigation.ejs b/docs/sections/navigation.ejs
index a1c1906..2d248a3 100644
--- a/docs/sections/navigation.ejs
+++ b/docs/sections/navigation.ejs
@@ -31,6 +31,7 @@
OptionButton
ProgressBar
Scrollbar
+ SearchBox
Slider
Spinner
Tabs
diff --git a/gui/_balloon.scss b/gui/_balloon.scss
index 85a15b7..316a91d 100644
--- a/gui/_balloon.scss
+++ b/gui/_balloon.scss
@@ -1,6 +1,9 @@
:root {
--balloon-border-color: rgba(0, 0, 0, 0.4);
+ --balloon-tail-top: url("data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0.5 1.5V19.5H18.5L0.5 1.5Z' fill='%23fff' stroke='%23fff'/%3E%3Cpath d='M1 19.5H0.5V1.5L18.5 19.5H18' stroke='%23939393'/%3E%3C/svg%3E");
+ --balloon-tail-bottom: url("data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0.5 1.5V19.5H18.5L0.5 1.5Z' fill='%23ddd' stroke='%23ddd'/%3E%3Cpath d='M1 19.5H0.5V1.5L18.5 19.5H18' stroke='%23939393'/%3E%3C/svg%3E");
--balloon-tail-size: 18px;
+ --balloon-tail-offset: 1em;
}
[role="tooltip"] {
@@ -14,14 +17,42 @@
&::before {
content: "";
position: absolute;
- background: url("./icon/balloon-tail.svg");
+ background: var(--balloon-tail-top);
width: var(--balloon-tail-size);
height: var(--balloon-tail-size);
top: -var(--balloon-tail-size);
- left: 1em;
+ left: var(--balloon-tail-offset);
}
&[id] {
position: absolute;
}
+
+ &.is-top {
+ &::before {
+ background: var(--balloon-tail-bottom);
+ bottom: -var(--balloon-tail-size);
+ top: unset;
+ transform: scale(-1);
+ }
+
+ &.is-right {
+ &::before {
+ transform: scaleY(-1);
+ }
+ }
+ }
+
+ &.is-left {
+ &::before {
+ left: unset;
+ right: var(--balloon-tail-offset);
+ }
+
+ &.is-bottom {
+ &::before {
+ transform: scaleX(-1);
+ }
+ }
+ }
}
diff --git a/gui/_button.scss b/gui/_button.scss
index cc1d779..cc7c5f6 100644
--- a/gui/_button.scss
+++ b/gui/_button.scss
@@ -11,12 +11,7 @@ button,
min-height: 23px;
padding: 0 12px;
text-align: center;
- background: linear-gradient(
- to bottom,
- var(--button-face) 45%,
- var(--button-shade-light) 45%,
- var(--button-shade-dark)
- );
+ background: var(--button-gradient);
&:disabled {
background: var(--button-face-disabled);
@@ -27,22 +22,14 @@ button,
&:not(:disabled) {
&:hover {
border-color: var(--button-border-color-hovered);
- background: linear-gradient(
- to bottom,
- var(--button-face-hover) 45%,
- var(--button-shade-light-hovered) 45%
- );
+ background: var(--button-gradient-hovered);
}
&:active,
&.active {
box-shadow: none;
border-color: var(--button-border-color-active);
- background: linear-gradient(
- to bottom,
- var(--button-face-active) 45%,
- var(--button-shade-light-active) 45%
- );
+ background: var(--button-gradient-active);
}
}
diff --git a/gui/_dropdown.scss b/gui/_dropdown.scss
index 2651c3a..da50913 100644
--- a/gui/_dropdown.scss
+++ b/gui/_dropdown.scss
@@ -12,24 +12,14 @@ select:not([multiple]) {
appearance: none;
position: relative;
padding-right: 30px;
- background: url("./icon/button-down.svg"),
- linear-gradient(
- to bottom,
- var(--button-face) 45%,
- var(--button-shade-light) 45%,
- var(--button-shade-dark)
- );
+ background: url("./icon/button-down.svg"), var(--button-gradient);
background-position: center right;
background-repeat: no-repeat;
&:hover {
border-color: var(--button-border-color-hovered);
background-image: url("./icon/button-down.svg"),
- linear-gradient(
- to bottom,
- var(--button-face-hover) 45%,
- var(--button-shade-light-hovered) 45%
- );
+ var(--button-gradient-hovered);
}
&:focus {
@@ -37,10 +27,6 @@ select:not([multiple]) {
border-color: var(--button-border-color-active);
box-shadow: unset;
background-image: url("./icon/button-down.svg"),
- linear-gradient(
- to bottom,
- var(--button-face-active) 45%,
- var(--button-shade-light-active) 45%
- );
+ var(--button-gradient-active);
}
}
diff --git a/gui/_searchbox.scss b/gui/_searchbox.scss
new file mode 100644
index 0000000..6201b35
--- /dev/null
+++ b/gui/_searchbox.scss
@@ -0,0 +1,63 @@
+:root {
+ --search-icon: url("./icon/search.svg");
+ --search-button: var(--search-icon) no-repeat center;
+}
+
+[type="search"] {
+ height: 24px;
+ font: var(--font);
+ padding: 3px 6px;
+ border: 1px solid transparent;
+ border-radius: 2px;
+ background-color: var(--button-highlight);
+ box-shadow: inset 1px 1px 0 var(--button-border-color), inset -1px -1px 0 #ccc;
+ box-sizing: border-box;
+ min-width: 187px;
+
+ &:placeholder-shown {
+ background-size: 14px;
+ background-position: calc(100% - 8px) center;
+ background-image: var(--search-icon);
+ background-repeat: no-repeat;
+ }
+
+ &:focus {
+ outline: none;
+ }
+
+ &::placeholder {
+ font-style: italic;
+ }
+
+ .searchbox & {
+ padding-right: 26px;
+
+ & + [aria-label="search"] {
+ position: absolute;
+ top: 1px;
+ right: 1px;
+ border-radius: 0;
+ padding: 0;
+ min-width: 26px;
+ min-height: 22px;
+ background: var(--search-button), var(--button-gradient);
+ background-size: 14px;
+
+ &:hover {
+ background: var(--search-button), var(--button-gradient-hovered);
+ background-size: 14px;
+ }
+
+ &:active {
+ background: var(--search-button), var(--button-gradient-active);
+ background-size: 14px;
+ box-shadow: inset 1px 1px 2px #37698f;
+ }
+ }
+ }
+}
+
+.searchbox {
+ position: relative;
+ display: inline-block;
+}
diff --git a/gui/_variables.scss b/gui/_variables.scss
index 14d4352..ff443c5 100644
--- a/gui/_variables.scss
+++ b/gui/_variables.scss
@@ -12,7 +12,8 @@
--button-shade-light-hovered: #b3e0f9;
--button-shade-light-active: #86c6e8;
--button-shade-dark: #bbb;
- --button-shadow: inset 0 -1px 1px rgba(255, 255, 255, 0.8), inset 0 1px 1px #fff;
+ --button-shadow: inset 0 -1px 1px rgba(255, 255, 255, 0.8),
+ inset 0 1px 1px #fff;
--button-border: 1px solid;
--button-border-color: #8e8f8f;
--button-border-color-default: #5586a3;
@@ -20,6 +21,22 @@
--button-border-color-active: #6d91ab;
--button-border-color-disabled: #aeb2b5;
--button-text-color-disabled: #838383;
+ --button-gradient: linear-gradient(
+ to bottom,
+ var(--button-face) 45%,
+ var(--button-shade-light) 45%,
+ var(--button-shade-dark)
+ );
+ --button-gradient-hovered: linear-gradient(
+ to bottom,
+ var(--button-face-hover) 45%,
+ var(--button-shade-light-hovered) 45%
+ );
+ --button-gradient-active: linear-gradient(
+ to bottom,
+ var(--button-face-active) 45%,
+ var(--button-shade-light-active) 45%
+ );
--element-spacing: 8px;
--grouped-element-spacing: 6px;
diff --git a/gui/icon/balloon-tail.svg b/gui/icon/balloon-tail.svg
deleted file mode 100644
index a9ade97..0000000
--- a/gui/icon/balloon-tail.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
diff --git a/gui/icon/search.svg b/gui/icon/search.svg
new file mode 100644
index 0000000..ff1e649
--- /dev/null
+++ b/gui/icon/search.svg
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/gui/index.scss b/gui/index.scss
index 324a092..d0ef29c 100644
--- a/gui/index.scss
+++ b/gui/index.scss
@@ -17,6 +17,7 @@
@import "_menu.scss";
@import "_progressbar.scss";
@import "_radiobutton.scss";
+@import "_searchbox.scss";
@import "_slider.scss";
@import "_spinner.scss";
@import "_tabs.scss";