@inglorious/ui 9.0.0 → 9.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/package.json +2 -2
  2. package/src/controls/button/button.stories.js +7 -1
  3. package/src/controls/button/style.css +11 -0
  4. package/src/controls/button/template.js +13 -12
  5. package/src/controls/button-group/template.js +6 -6
  6. package/src/controls/checkbox/checkbox.stories.js +12 -0
  7. package/src/controls/checkbox/style.css +11 -0
  8. package/src/controls/checkbox/template.js +11 -1
  9. package/src/controls/file-upload/template.js +27 -26
  10. package/src/controls/icon-button/template.js +6 -6
  11. package/src/controls/image-cropper/template.js +3 -1
  12. package/src/controls/radio-group/radio-group.stories.js +21 -1
  13. package/src/controls/radio-group/style.css +11 -0
  14. package/src/controls/radio-group/template.js +15 -6
  15. package/src/controls/rating/rating.stories.js +8 -0
  16. package/src/controls/select/template.js +5 -6
  17. package/src/controls/slider/slider.stories.js +28 -1
  18. package/src/controls/slider/style.css +102 -0
  19. package/src/controls/slider/template.js +131 -29
  20. package/src/controls/switch/style.css +11 -0
  21. package/src/controls/switch/switch.stories.js +10 -0
  22. package/src/controls/switch/template.js +15 -1
  23. package/src/controls/textarea/template.js +29 -26
  24. package/src/data-display/avatar/template.js +6 -5
  25. package/src/data-display/chip/chip.stories.js +17 -0
  26. package/src/data-display/chip/style.css +5 -0
  27. package/src/data-display/chip/template.js +11 -8
  28. package/src/data-display/data-grid/template.js +1 -1
  29. package/src/data-display/divider/divider.stories.js +9 -0
  30. package/src/data-display/divider/template.js +12 -4
  31. package/src/data-display/list/template.js +4 -5
  32. package/src/examples/dashboard/primitive-section.js +18 -18
  33. package/src/feedback/alert/alert.stories.js +9 -1
  34. package/src/feedback/alert/style.css +5 -0
  35. package/src/feedback/alert/template.js +28 -27
  36. package/src/feedback/dialog/dialog.stories.js +22 -0
  37. package/src/feedback/dialog/style.css +15 -2
  38. package/src/feedback/dialog/template.js +37 -30
  39. package/src/feedback/progress/progress.stories.js +5 -0
  40. package/src/feedback/snackbar/template.js +14 -13
  41. package/src/layout/flex/flex.stories.js +1 -1
  42. package/src/layout/flex/style.css +8 -0
  43. package/src/navigation/bottom-navigation/template.js +11 -12
  44. package/src/navigation/breadcrumbs/template.js +28 -25
  45. package/src/navigation/menu/template.js +9 -10
  46. package/src/navigation/pagination/template.js +15 -18
  47. package/src/navigation/stepper/template.js +5 -5
  48. package/src/navigation/tabs/template.js +2 -1
  49. package/src/surfaces/accordion/accordion.stories.js +9 -0
  50. package/src/surfaces/accordion/template.js +7 -2
  51. package/src/surfaces/card/card.stories.js +24 -0
  52. package/src/surfaces/card/style.css +15 -0
  53. package/src/surfaces/card/template.js +5 -2
  54. package/types/controls/button.d.ts +1 -1
  55. package/types/controls/checkbox.d.ts +2 -0
  56. package/types/controls/radio-group.d.ts +2 -0
  57. package/types/controls/slider.d.ts +6 -2
  58. package/types/controls/switch.d.ts +2 -0
  59. package/types/data-display/chip.d.ts +2 -0
  60. package/types/data-display/divider.d.ts +2 -0
  61. package/types/feedback/alert.d.ts +1 -1
  62. package/types/feedback/dialog.d.ts +2 -0
  63. package/types/layout/flex.d.ts +1 -1
  64. package/types/surfaces/card.d.ts +5 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inglorious/ui",
3
- "version": "9.0.0",
3
+ "version": "9.1.1",
4
4
  "description": "A design system for Inglorious Web with render-function components and customizable themes",
5
5
  "author": "Matteo Antony Mistretta <antony.mistretta@gmail.com> (https://ingloriouscoderz.it)",
6
6
  "license": "MIT",
@@ -315,7 +315,7 @@
315
315
  "@iconify-icons/fa7-regular": "^2.0.0",
316
316
  "@iconify-icons/fa7-solid": "^2.0.0",
317
317
  "@iconify-icons/material-symbols": "^2.0.6",
318
- "@inglorious/charts": "11.1.7",
318
+ "@inglorious/charts": "12.1.0",
319
319
  "@inglorious/eslint-config": "1.2.0",
320
320
  "@inglorious/store": "12.0.0",
321
321
  "@inglorious/vite-plugin-jsx": "2.0.5",
@@ -32,7 +32,7 @@ export default {
32
32
  },
33
33
  size: {
34
34
  control: "select",
35
- options: ["sm", "md", "lg"],
35
+ options: ["xs", "sm", "md", "lg"],
36
36
  description: "Size scale for paddings and font-size.",
37
37
  },
38
38
  shape: {
@@ -106,6 +106,12 @@ Ghost.args = {
106
106
  variant: "ghost",
107
107
  }
108
108
 
109
+ export const ExtraSmall = {}
110
+ ExtraSmall.args = {
111
+ ...Default.args,
112
+ size: "xs",
113
+ }
114
+
109
115
  export const Small = {}
110
116
  Small.args = {
111
117
  ...Default.args,
@@ -153,6 +153,11 @@
153
153
  cursor: not-allowed;
154
154
  }
155
155
 
156
+ &.iw-button-xs {
157
+ padding: var(--iw-space-0) var(--iw-space-2);
158
+ font-size: var(--iw-font-size-xs);
159
+ }
160
+
156
161
  &.iw-button-sm {
157
162
  padding: var(--iw-space-1) var(--iw-space-3);
158
163
  font-size: var(--iw-font-size-sm);
@@ -179,6 +184,12 @@
179
184
  border-radius: var(--iw-radius-sm);
180
185
  }
181
186
 
187
+ &.iw-button-xs.iw-button-shape-round,
188
+ &.iw-button-xs.iw-button-shape-square {
189
+ width: 1.5rem;
190
+ height: 1.5rem;
191
+ }
192
+
182
193
  &.iw-button-sm.iw-button-shape-round,
183
194
  &.iw-button-sm.iw-button-shape-square {
184
195
  width: 2rem;
@@ -6,6 +6,7 @@
6
6
  import { html, nothing } from "@inglorious/web"
7
7
  import { classMap } from "@inglorious/web/directives/class-map"
8
8
  import { ref } from "@inglorious/web/directives/ref"
9
+ import { when } from "@inglorious/web/directives/when"
9
10
 
10
11
  import { applyElementProps } from "../../shared/apply-element-props.js"
11
12
 
@@ -83,18 +84,18 @@ export function render(props) {
83
84
  >
84
85
  ${children}
85
86
  </button>
86
- ${
87
- onFileSelect
88
- ? html`<input
89
- type="file"
90
- accept=${accept ?? ""}
91
- ?multiple=${isMultiple}
92
- ?disabled=${isDisabled}
93
- hidden
94
- @change=${(event) => handleFileChange(event, onFileSelect)}
95
- />`
96
- : nothing
97
- }
87
+ ${when(
88
+ onFileSelect,
89
+ () =>
90
+ html`<input
91
+ type="file"
92
+ accept=${accept ?? ""}
93
+ ?multiple=${isMultiple}
94
+ ?disabled=${isDisabled}
95
+ hidden
96
+ @change=${(event) => handleFileChange(event, onFileSelect)}
97
+ />`,
98
+ )}
98
99
  `
99
100
  }
100
101
 
@@ -6,6 +6,7 @@
6
6
  import { html } from "@inglorious/web"
7
7
  import { classMap } from "@inglorious/web/directives/class-map"
8
8
  import { ref } from "@inglorious/web/directives/ref"
9
+ import { when } from "@inglorious/web/directives/when"
9
10
 
10
11
  import { applyElementProps } from "../../shared/apply-element-props.js"
11
12
  import { Button } from "../button/index.js"
@@ -73,13 +74,12 @@ export function render(props) {
73
74
 
74
75
  return Button.render({
75
76
  children: html`
76
- ${icon ? html`<span class="iw-button-icon">${icon}</span>` : null}
77
+ ${when(icon, () => html`<span class="iw-button-icon">${icon}</span>`)}
77
78
  ${children ?? label}
78
- ${
79
- iconAfter
80
- ? html`<span class="iw-button-icon">${iconAfter}</span>`
81
- : null
82
- }
79
+ ${when(
80
+ iconAfter,
81
+ () => html`<span class="iw-button-icon">${iconAfter}</span>`,
82
+ )}
83
83
  `,
84
84
  variant: itemVariant ?? variant,
85
85
  color: itemColor ?? color,
@@ -7,6 +7,10 @@ export default {
7
7
  render: createRender(Checkbox),
8
8
  argTypes: {
9
9
  label: { control: "text", description: "Label text." },
10
+ description: {
11
+ control: "text",
12
+ description: "A line of detail under the label.",
13
+ },
10
14
  name: { control: "text", description: "Native HTML name attribute." },
11
15
  isChecked: { control: "boolean", description: "Current checked state." },
12
16
  isDisabled: { control: "boolean", description: "Disables interaction." },
@@ -48,3 +52,11 @@ Checked.args = {
48
52
  ...Default.args,
49
53
  isChecked: true,
50
54
  }
55
+
56
+ export const WithDescription = {}
57
+ WithDescription.args = {
58
+ ...Default.args,
59
+ label: "Weekly summary",
60
+ name: "summary",
61
+ description: "An email every Monday with last week's totals.",
62
+ }
@@ -14,6 +14,17 @@
14
14
  accent-color: var(--iw-checkbox-accent);
15
15
  }
16
16
 
17
+ /* With a description, the label and it stack beside the box. */
18
+ .iw-checkbox-text {
19
+ display: flex;
20
+ flex-direction: column;
21
+ }
22
+
23
+ .iw-checkbox-description {
24
+ font-size: var(--iw-font-size-sm);
25
+ color: var(--iw-color-text-secondary);
26
+ }
27
+
17
28
  .iw-checkbox-label {
18
29
  font-size: var(--iw-font-size-base);
19
30
  line-height: var(--iw-line-height-normal);
@@ -6,6 +6,7 @@
6
6
  import { html, nothing } from "@inglorious/web"
7
7
  import { classMap } from "@inglorious/web/directives/class-map"
8
8
  import { ref } from "@inglorious/web/directives/ref"
9
+ import { when } from "@inglorious/web/directives/when"
9
10
 
10
11
  import { applyElementProps } from "../../shared/apply-element-props.js"
11
12
 
@@ -21,6 +22,7 @@ export function render(props) {
21
22
  type, // eslint-disable-line no-unused-vars
22
23
  name = "",
23
24
  label = "",
25
+ description,
24
26
  isChecked = false,
25
27
  isDisabled = false,
26
28
  isRequired = false,
@@ -54,7 +56,15 @@ export function render(props) {
54
56
  @change=${(event) => onChange?.(event.target.checked)}
55
57
  ${ref((element) => applyElementProps(element, rest))}
56
58
  />
57
- <span class="iw-checkbox-label">${label}</span>
59
+ ${when(
60
+ description,
61
+ () =>
62
+ html`<span class="iw-checkbox-text">
63
+ <span class="iw-checkbox-label">${label}</span>
64
+ <span class="iw-checkbox-description">${description}</span>
65
+ </span>`,
66
+ () => html`<span class="iw-checkbox-label">${label}</span>`,
67
+ )}
58
68
  </label>
59
69
  `
60
70
  }
@@ -6,6 +6,7 @@
6
6
  import { html, nothing } from "@inglorious/web"
7
7
  import { classMap } from "@inglorious/web/directives/class-map"
8
8
  import { ref } from "@inglorious/web/directives/ref"
9
+ import { when } from "@inglorious/web/directives/when"
9
10
 
10
11
  import { applyElementProps } from "../../shared/apply-element-props.js"
11
12
  import { fallbackLabel } from "../../shared/fallback-label.js"
@@ -57,20 +58,18 @@ export function render(props) {
57
58
 
58
59
  return html`
59
60
  <div class=${classMap(wrapperClasses)}>
60
- ${
61
- label
62
- ? html`
63
- <label for=${uploadId || nothing} class="iw-upload-label">
64
- ${label}
65
- ${
66
- isRequired
67
- ? html`<span class="iw-upload-required">*</span>`
68
- : null
69
- }
70
- </label>
71
- `
72
- : null
73
- }
61
+ ${when(
62
+ label,
63
+ () => html`
64
+ <label for=${uploadId || nothing} class="iw-upload-label">
65
+ ${label}
66
+ ${when(
67
+ isRequired,
68
+ () => html`<span class="iw-upload-required">*</span>`,
69
+ )}
70
+ </label>
71
+ `,
72
+ )}
74
73
 
75
74
  <div class=${classMap(fieldClasses)}>
76
75
  <input
@@ -99,19 +98,21 @@ export function render(props) {
99
98
 
100
99
  <div class="iw-upload-field-summary">${summaryText}</div>
101
100
 
102
- ${
103
- error
104
- ? html`<span
105
- id=${messageId || nothing}
106
- class="iw-upload-error-message"
107
- >${error}</span
108
- >`
109
- : hint
110
- ? html`<span id=${messageId || nothing} class="iw-upload-hint"
101
+ ${when(
102
+ error,
103
+ () =>
104
+ html`<span id=${messageId || nothing} class="iw-upload-error-message"
105
+ >${error}</span
106
+ >`,
107
+ () =>
108
+ when(
109
+ hint,
110
+ () =>
111
+ html`<span id=${messageId || nothing} class="iw-upload-hint"
111
112
  >${hint}</span
112
- >`
113
- : null
114
- }
113
+ >`,
114
+ ),
115
+ )}
115
116
  </div>
116
117
  `
117
118
  }
@@ -4,6 +4,7 @@
4
4
  */
5
5
 
6
6
  import { html } from "@inglorious/web"
7
+ import { when } from "@inglorious/web/directives/when"
7
8
 
8
9
  import { Button } from "../button/index.js"
9
10
 
@@ -25,13 +26,12 @@ export function render(props) {
25
26
 
26
27
  const children = html`
27
28
  <span class="iw-icon-button-content iw-icon-button-content-${direction}">
28
- ${icon ? html`<span class="iw-button-icon">${icon}</span>` : null}
29
+ ${when(icon, () => html`<span class="iw-button-icon">${icon}</span>`)}
29
30
  ${label}
30
- ${
31
- iconAfter
32
- ? html`<span class="iw-button-icon">${iconAfter}</span>`
33
- : null
34
- }
31
+ ${when(
32
+ iconAfter,
33
+ () => html`<span class="iw-button-icon">${iconAfter}</span>`,
34
+ )}
35
35
  </span>
36
36
  `
37
37
 
@@ -6,6 +6,7 @@
6
6
 
7
7
  import { html } from "@inglorious/web"
8
8
  import { classMap } from "@inglorious/web/directives/class-map"
9
+ import { when } from "@inglorious/web/directives/when"
9
10
 
10
11
  import {
11
12
  DEFAULT_MIN_SIZE,
@@ -84,7 +85,8 @@ export const ImageCropper = {
84
85
  @keydown=${handleKeyDown(props)}
85
86
  @wheel=${handleWheel(props)}
86
87
  >
87
- ${this.renderImage?.(props)} ${isLoaded ? this.renderFrame?.(props) : ""}
88
+ ${this.renderImage?.(props)}
89
+ ${when(isLoaded, () => this.renderFrame?.(props))}
88
90
  </div>`
89
91
  },
90
92
 
@@ -20,7 +20,11 @@ export default {
20
20
  description: "Semantic accent color.",
21
21
  },
22
22
  isDisabled: { control: "boolean", description: "Disables all options." },
23
- options: { control: "object", description: "List of radio options." },
23
+ options: {
24
+ control: "object",
25
+ description:
26
+ "List of radio options: `label`, `value`, and an optional `description` under the label.",
27
+ },
24
28
  onChange: { action: "onChange" },
25
29
  },
26
30
  parameters: {
@@ -52,3 +56,19 @@ Row.args = {
52
56
  ...Default.args,
53
57
  direction: "row",
54
58
  }
59
+
60
+ export const WithDescriptions = {}
61
+ WithDescriptions.args = {
62
+ ...Default.args,
63
+ label: "Shipping",
64
+ name: "shipping",
65
+ value: "standard",
66
+ options: [
67
+ {
68
+ label: "Standard",
69
+ value: "standard",
70
+ description: "3 to 5 working days, free",
71
+ },
72
+ { label: "Express", value: "express", description: "Next day, €9" },
73
+ ],
74
+ }
@@ -19,6 +19,17 @@
19
19
  cursor: pointer;
20
20
  }
21
21
 
22
+ /* With a description, the label and it stack beside the circle. */
23
+ .iw-radio-text {
24
+ display: flex;
25
+ flex-direction: column;
26
+ }
27
+
28
+ .iw-radio-description {
29
+ font-size: var(--iw-font-size-sm);
30
+ color: var(--iw-color-text-secondary);
31
+ }
32
+
22
33
  .iw-radio {
23
34
  margin: 0;
24
35
  accent-color: var(--iw-radio-accent);
@@ -6,6 +6,7 @@
6
6
  import { html, nothing } from "@inglorious/web"
7
7
  import { classMap } from "@inglorious/web/directives/class-map"
8
8
  import { ref } from "@inglorious/web/directives/ref"
9
+ import { when } from "@inglorious/web/directives/when"
9
10
 
10
11
  import { applyElementProps } from "../../shared/apply-element-props.js"
11
12
 
@@ -47,14 +48,14 @@ export function render(props) {
47
48
  ?disabled=${isDisabled}
48
49
  ${ref((element) => applyElementProps(element, rest))}
49
50
  >
50
- ${
51
- label
52
- ? html`<legend class="iw-radio-group-label">${label}</legend>`
53
- : null
54
- }
51
+ ${when(
52
+ label,
53
+ () => html`<legend class="iw-radio-group-label">${label}</legend>`,
54
+ )}
55
55
  ${options.map((option, index) => {
56
56
  const {
57
57
  label: optionLabel,
58
+ description: optionDescription,
58
59
  value: optionValue,
59
60
  isDisabled: optionDisabled = false,
60
61
  ...optionRest
@@ -73,7 +74,15 @@ export function render(props) {
73
74
  @change=${(event) => onChange?.(event.target.value)}
74
75
  ${ref((element) => applyElementProps(element, optionRest))}
75
76
  />
76
- <span>${optionLabel}</span>
77
+ ${when(
78
+ optionDescription,
79
+ () =>
80
+ html`<span class="iw-radio-text">
81
+ <span>${optionLabel}</span>
82
+ <span class="iw-radio-description">${optionDescription}</span>
83
+ </span>`,
84
+ () => html`<span>${optionLabel}</span>`,
85
+ )}
77
86
  </label>
78
87
  `
79
88
  })}
@@ -8,6 +8,14 @@ export default {
8
8
  argTypes: {
9
9
  value: { control: "number", description: "Current rating value." },
10
10
  max: { control: "number", description: "Maximum rating value." },
11
+ name: {
12
+ control: "text",
13
+ description: "Groups the radios and names the value in a form.",
14
+ },
15
+ ariaLabel: {
16
+ control: "text",
17
+ description: 'Names the group for assistive tech. Defaults to "Rating".',
18
+ },
11
19
  isDisabled: { control: "boolean", description: "Disables interaction." },
12
20
  isReadOnly: {
13
21
  control: "boolean",
@@ -52,11 +52,10 @@ export const Select = {
52
52
  () => html`
53
53
  <label for=${id || name || nothing} class="iw-select-label">
54
54
  ${label}
55
- ${
56
- isRequired
57
- ? html`<span class="iw-select-required">*</span>`
58
- : null
59
- }
55
+ ${when(
56
+ isRequired,
57
+ () => html`<span class="iw-select-required">*</span>`,
58
+ )}
60
59
  </label>
61
60
  `,
62
61
  )}
@@ -117,7 +116,7 @@ export const Select = {
117
116
  )
118
117
 
119
118
  return html`<div class="iw-select-frame" @click=${openFromArrowStrip}>
120
- ${icon ? Icon.render({ children: icon, size }) : null}
119
+ ${when(icon, () => Icon.render({ children: icon, size }))}
121
120
 
122
121
  <select
123
122
  id=${controlId || nothing}
@@ -8,7 +8,11 @@ export default {
8
8
  argTypes: {
9
9
  label: { control: "text", description: "Field label." },
10
10
  name: { control: "text", description: "Native input name." },
11
- value: { control: "number", description: "Current slider value." },
11
+ value: {
12
+ control: "object",
13
+ description:
14
+ "One number, or `[low, high]` for a range with a thumb at each end.",
15
+ },
12
16
  min: { control: "number", description: "Minimum value." },
13
17
  max: { control: "number", description: "Maximum value." },
14
18
  step: { control: "number", description: "Step value." },
@@ -20,6 +24,10 @@ export default {
20
24
  isDisabled: { control: "boolean", description: "Disables interaction." },
21
25
  isValueVisible: { control: "boolean", description: "Shows current value." },
22
26
  isFullWidth: { control: "boolean", description: "Expands width to 100%." },
27
+ hasMarks: {
28
+ control: "boolean",
29
+ description: "Draws a tick at every step.",
30
+ },
23
31
  onChange: { action: "onChange" },
24
32
  },
25
33
  parameters: {
@@ -44,3 +52,22 @@ Default.args = {
44
52
  isValueVisible: true,
45
53
  isFullWidth: false,
46
54
  }
55
+
56
+ export const Range = {}
57
+ Range.args = {
58
+ ...Default.args,
59
+ label: "Price",
60
+ name: "price",
61
+ value: [20, 80],
62
+ }
63
+
64
+ export const Marks = {}
65
+ Marks.args = {
66
+ ...Default.args,
67
+ label: "Rating",
68
+ name: "rating",
69
+ value: 3,
70
+ min: 1,
71
+ max: 5,
72
+ hasMarks: true,
73
+ }
@@ -23,6 +23,108 @@
23
23
  accent-color: var(--iw-slider-accent);
24
24
  }
25
25
 
26
+ /* A tick per step, under the track: their ends sit under the thumb's ends
27
+ of travel, half a thumb in from the track's. */
28
+ .iw-slider-marks {
29
+ display: flex;
30
+ justify-content: space-between;
31
+ padding-inline: calc(var(--iw-slider-thumb, 1rem) / 2);
32
+
33
+ span {
34
+ inline-size: 1px;
35
+ block-size: var(--iw-space-2);
36
+ background: var(--iw-color-border);
37
+ }
38
+ }
39
+
40
+ /* Two thumbs on one track. The inputs lie on top of each other with their
41
+ own tracks hidden, and only their thumbs take presses, so either can be
42
+ dragged; the track below is drawn here, filled between the two. */
43
+ &.iw-slider-range {
44
+ --iw-slider-thumb: 1rem;
45
+
46
+ .iw-slider-track {
47
+ position: relative;
48
+ block-size: var(--iw-slider-thumb);
49
+
50
+ &::before,
51
+ &::after {
52
+ content: "";
53
+ position: absolute;
54
+ inset-block-start: 50%;
55
+ block-size: 0.25rem;
56
+ translate: 0 -50%;
57
+ border-radius: var(--iw-radius-full, 999px);
58
+ }
59
+
60
+ &::before {
61
+ inset-inline: 0;
62
+ background: color-mix(
63
+ in srgb,
64
+ var(--iw-slider-accent) 25%,
65
+ transparent
66
+ );
67
+ }
68
+
69
+ &::after {
70
+ inset-inline-start: var(--iw-slider-low);
71
+ inset-inline-end: calc(100% - var(--iw-slider-high));
72
+ background: var(--iw-slider-accent);
73
+ }
74
+ }
75
+
76
+ .iw-slider-input {
77
+ position: absolute;
78
+ inset: 0;
79
+ z-index: 1;
80
+ margin: 0;
81
+ appearance: none;
82
+ background: transparent;
83
+ pointer-events: none;
84
+
85
+ &::-webkit-slider-runnable-track {
86
+ background: transparent;
87
+ }
88
+
89
+ &::-moz-range-track {
90
+ background: transparent;
91
+ }
92
+
93
+ &::-webkit-slider-thumb {
94
+ appearance: none;
95
+ inline-size: var(--iw-slider-thumb);
96
+ block-size: var(--iw-slider-thumb);
97
+ border: 2px solid var(--iw-color-surface);
98
+ border-radius: 50%;
99
+ background: var(--iw-slider-accent);
100
+ box-shadow: var(--iw-shadow-sm);
101
+ cursor: pointer;
102
+ pointer-events: auto;
103
+ }
104
+
105
+ &::-moz-range-thumb {
106
+ inline-size: var(--iw-slider-thumb);
107
+ block-size: var(--iw-slider-thumb);
108
+ border: 2px solid var(--iw-color-surface);
109
+ border-radius: 50%;
110
+ background: var(--iw-slider-accent);
111
+ box-shadow: var(--iw-shadow-sm);
112
+ cursor: pointer;
113
+ pointer-events: auto;
114
+ }
115
+
116
+ &:focus-visible::-webkit-slider-thumb {
117
+ outline: 2px solid var(--iw-slider-accent);
118
+ outline-offset: 2px;
119
+ }
120
+
121
+ &:focus-visible::-moz-range-thumb {
122
+ outline: 2px solid var(--iw-slider-accent);
123
+ outline-offset: 2px;
124
+ }
125
+ }
126
+ }
127
+
26
128
  &.iw-slider-full-width {
27
129
  width: 100%;
28
130
  }