@hakumi-dev/hakumi-components 0.1.18-pre → 0.1.19-pre

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 (56) hide show
  1. package/README.md +208 -381
  2. package/app/javascript/hakumi_components/controllers/hakumi/admin_panel_controller.js +5 -7
  3. package/app/javascript/hakumi_components/controllers/hakumi/back_top_controller.js +1 -1
  4. package/app/javascript/hakumi_components/controllers/hakumi/button_controller.js +108 -2
  5. package/app/javascript/hakumi_components/controllers/hakumi/calendar_controller.js +183 -95
  6. package/app/javascript/hakumi_components/controllers/hakumi/color_picker_controller.js +23 -285
  7. package/app/javascript/hakumi_components/controllers/hakumi/date_picker_controller.js +274 -262
  8. package/app/javascript/hakumi_components/controllers/hakumi/float_button_group_controller.js +2 -2
  9. package/app/javascript/hakumi_components/controllers/hakumi/message_controller.js +4 -2
  10. package/app/javascript/hakumi_components/controllers/hakumi/modal_controller.js +119 -125
  11. package/app/javascript/hakumi_components/controllers/hakumi/table/editable.js +291 -0
  12. package/app/javascript/hakumi_components/controllers/hakumi/table_controller.js +166 -366
  13. package/app/javascript/hakumi_components/controllers/hakumi/tabs_controller.js +8 -2
  14. package/app/javascript/hakumi_components/controllers/hakumi/tag_controller.js +27 -25
  15. package/app/javascript/hakumi_components/controllers/hakumi/tag_group_controller.js +19 -18
  16. package/app/javascript/hakumi_components/controllers/hakumi/theme_controller.js +116 -117
  17. package/app/javascript/hakumi_components/controllers/hakumi/transfer_controller.js +17 -1
  18. package/app/javascript/hakumi_components/controllers/hakumi/tree_controller.js +363 -78
  19. package/app/javascript/hakumi_components/controllers/hakumi/typography_controller.js +3 -3
  20. package/app/javascript/hakumi_components/controllers/hakumi/upload_controller.js +320 -204
  21. package/app/javascript/hakumi_components/core/render_component.js +37 -11
  22. package/app/javascript/hakumi_components/utils/color_helper.js +262 -0
  23. package/app/javascript/stylesheets/_base.scss +9 -0
  24. package/app/javascript/stylesheets/_hakumi_components.scss +1 -0
  25. package/app/javascript/stylesheets/components/_breadcrumb.scss +2 -2
  26. package/app/javascript/stylesheets/components/_calendar.scss +13 -13
  27. package/app/javascript/stylesheets/components/_cascader.scss +5 -5
  28. package/app/javascript/stylesheets/components/_checkbox.scss +9 -11
  29. package/app/javascript/stylesheets/components/_color_picker.scss +11 -11
  30. package/app/javascript/stylesheets/components/_date_picker.scss +4 -4
  31. package/app/javascript/stylesheets/components/_descriptions.scss +2 -2
  32. package/app/javascript/stylesheets/components/_drawer.scss +3 -3
  33. package/app/javascript/stylesheets/components/_dropdown.scss +2 -2
  34. package/app/javascript/stylesheets/components/_flex.scss +1 -1
  35. package/app/javascript/stylesheets/components/_float_button.scss +5 -5
  36. package/app/javascript/stylesheets/components/_form_item.scss +92 -0
  37. package/app/javascript/stylesheets/components/_image.scss +15 -15
  38. package/app/javascript/stylesheets/components/_input.scss +23 -113
  39. package/app/javascript/stylesheets/components/_layout.scss +27 -26
  40. package/app/javascript/stylesheets/components/_menu.scss +15 -15
  41. package/app/javascript/stylesheets/components/_modal.scss +13 -13
  42. package/app/javascript/stylesheets/components/_notification.scss +3 -3
  43. package/app/javascript/stylesheets/components/_popover.scss +1 -1
  44. package/app/javascript/stylesheets/components/_segmented.scss +3 -3
  45. package/app/javascript/stylesheets/components/_select.scss +6 -6
  46. package/app/javascript/stylesheets/components/_slider.scss +1 -1
  47. package/app/javascript/stylesheets/components/_spin.scss +2 -2
  48. package/app/javascript/stylesheets/components/_steps.scss +10 -10
  49. package/app/javascript/stylesheets/components/_switch.scss +11 -10
  50. package/app/javascript/stylesheets/components/_table.scss +6 -6
  51. package/app/javascript/stylesheets/components/_tag.scss +2 -2
  52. package/app/javascript/stylesheets/components/_tooltip.scss +4 -4
  53. package/app/javascript/stylesheets/components/_tree_select.scss +3 -3
  54. package/app/javascript/stylesheets/components/_typography.scss +3 -3
  55. package/app/javascript/stylesheets/components/_upload.scss +4 -4
  56. package/package.json +2 -2
@@ -31,32 +31,48 @@ const isInIframe = () => {
31
31
  }
32
32
 
33
33
 
34
- const cacheKeyFor = (normalizedName, format) => `hakumi:rcache:${format}:${normalizedName}`
35
- const cacheMetaKeyFor = (normalizedName, format) => `hakumi:rcachemeta:${format}:${normalizedName}`
34
+ const stableParamHash = (params) => {
35
+ const sorted = Object.keys(params).sort().map(k => `${k}=${params[k]}`).join("&")
36
+ if (!sorted) return ""
37
+ let h = 0
38
+ for (let i = 0; i < sorted.length; i++) {
39
+ h = ((h << 5) - h + sorted.charCodeAt(i)) | 0
40
+ }
41
+ return h.toString(36)
42
+ }
43
+
44
+ const cacheKeyFor = (normalizedName, format, params = {}) => {
45
+ const ph = stableParamHash(params)
46
+ return `hakumi:rcache:${format}:${normalizedName}${ph ? `:${ph}` : ""}`
47
+ }
48
+ const cacheMetaKeyFor = (normalizedName, format, params = {}) => {
49
+ const ph = stableParamHash(params)
50
+ return `hakumi:rcachemeta:${format}:${normalizedName}${ph ? `:${ph}` : ""}`
51
+ }
36
52
 
37
53
  const resolveComponentData = (element) => element?.hakumiComponent
38
54
 
39
- const loadCache = (normalizedName, format, ttlMs) => {
40
- const metaRaw = safeSessionGet(cacheMetaKeyFor(normalizedName, format))
55
+ const loadCache = (normalizedName, format, ttlMs, params = {}) => {
56
+ const metaRaw = safeSessionGet(cacheMetaKeyFor(normalizedName, format, params))
41
57
  if (!metaRaw) return null
42
58
 
43
59
  let meta
44
60
  try {
45
61
  meta = JSON.parse(metaRaw)
46
62
  } catch {
47
- safeSessionRemove(cacheMetaKeyFor(normalizedName, format))
63
+ safeSessionRemove(cacheMetaKeyFor(normalizedName, format, params))
48
64
  return null
49
65
  }
50
66
 
51
67
  if (!meta?.ts || typeof meta.ts !== "number") return null
52
68
  if (ttlMs != null && Date.now() - meta.ts > ttlMs) return null
53
69
 
54
- return safeSessionGet(cacheKeyFor(normalizedName, format))
70
+ return safeSessionGet(cacheKeyFor(normalizedName, format, params))
55
71
  }
56
72
 
57
- const saveCache = (normalizedName, format, html) => {
58
- safeSessionSet(cacheKeyFor(normalizedName, format), html)
59
- safeSessionSet(cacheMetaKeyFor(normalizedName, format), JSON.stringify({ ts: Date.now() }))
73
+ const saveCache = (normalizedName, format, html, params = {}) => {
74
+ safeSessionSet(cacheKeyFor(normalizedName, format, params), html)
75
+ safeSessionSet(cacheMetaKeyFor(normalizedName, format, params), JSON.stringify({ ts: Date.now() }))
60
76
  }
61
77
 
62
78
  export const renderComponent = async (
@@ -112,11 +128,12 @@ export const renderComponent = async (
112
128
 
113
129
  let optimisticElement = null
114
130
  if (cache && mode !== "replace") {
115
- const cachedHtml = loadCache(normalizedName, format, cacheTtlMs)
131
+ const cachedHtml = loadCache(normalizedName, format, cacheTtlMs, finalParams)
116
132
  if (cachedHtml) {
117
133
  try {
118
134
  optimisticElement = elementFromHtml(cachedHtml, name)
119
135
  optimisticElement.setAttribute("data-hakumi-render-cache", "1")
136
+ optimisticElement.setAttribute("data-hakumi-render-pending", "")
120
137
  resolvedTarget.appendChild(optimisticElement)
121
138
  ensureId(optimisticElement, `hakumi-${name}`)
122
139
  } catch {}
@@ -129,9 +146,14 @@ export const renderComponent = async (
129
146
 
130
147
  const html = format === "json" ? (await response.json()).html : await response.text()
131
148
 
132
- if (cache) saveCache(normalizedName, format, html)
149
+ if (cache) saveCache(normalizedName, format, html, finalParams)
133
150
 
134
151
  const element = elementFromHtml(html, name)
152
+ const optimisticWasReady = optimisticElement?.dataset.hakumiReady === "true"
153
+
154
+ if (!optimisticWasReady) {
155
+ element.setAttribute("data-hakumi-render-pending", "")
156
+ }
135
157
 
136
158
  if (mode === "replace") {
137
159
  resolvedTarget.innerHTML = ""
@@ -156,6 +178,10 @@ export const renderComponent = async (
156
178
 
157
179
  await nextFrame()
158
180
 
181
+ if (element.dataset.hakumiRenderPending !== undefined && element.dataset.hakumiReady !== "true") {
182
+ element.dataset.hakumiReady = "true"
183
+ }
184
+
159
185
  let instance = get(id)
160
186
  if (!instance) {
161
187
  register(id, element)
@@ -0,0 +1,262 @@
1
+ const DEFAULT_HSV = Object.freeze({ h: 215, s: 91, v: 100 })
2
+
3
+ export function defaultHsv() {
4
+ return { ...DEFAULT_HSV }
5
+ }
6
+
7
+ export function formatHsvColor(hsv, alpha, format, { disabledAlpha = false } = {}) {
8
+ switch (format) {
9
+ case "hex":
10
+ return hsvToHex(hsv.h, hsv.s, hsv.v, alpha, { disabledAlpha })
11
+ case "rgb":
12
+ return hsvToRgbString(hsv.h, hsv.s, hsv.v, alpha, { disabledAlpha })
13
+ case "hsl":
14
+ return hsvToHslString(hsv.h, hsv.s, hsv.v, alpha, { disabledAlpha })
15
+ case "hsb":
16
+ return hsvToHsbString(hsv.h, hsv.s, hsv.v, alpha, { disabledAlpha })
17
+ default:
18
+ return hsvToHex(hsv.h, hsv.s, hsv.v, alpha, { disabledAlpha })
19
+ }
20
+ }
21
+
22
+ export function parseColorToHsv(color) {
23
+ if (!color) return defaultHsv()
24
+
25
+ const normalizedColor = color.trim()
26
+
27
+ if (normalizedColor.startsWith("#")) {
28
+ return hexToHsv(normalizedColor)
29
+ }
30
+
31
+ if (normalizedColor.startsWith("rgb")) {
32
+ return rgbStringToHsv(normalizedColor)
33
+ }
34
+
35
+ if (normalizedColor.startsWith("hsl")) {
36
+ return hslStringToHsv(normalizedColor)
37
+ }
38
+
39
+ if (normalizedColor.startsWith("hsb")) {
40
+ return hsbStringToHsv(normalizedColor)
41
+ }
42
+
43
+ return defaultHsv()
44
+ }
45
+
46
+ export function extractAlpha(color) {
47
+ if (!color) return 1
48
+
49
+ const normalizedColor = color.trim()
50
+
51
+ if (normalizedColor.startsWith("rgba")) {
52
+ const match = normalizedColor.match(/rgba?\(([^)]+)\)/)
53
+ if (match) {
54
+ const parts = match[1].split(",").map(part => part.trim())
55
+ if (parts[3]) return parseFloat(parts[3])
56
+ }
57
+ }
58
+
59
+ if (normalizedColor.startsWith("hsla")) {
60
+ const match = normalizedColor.match(/hsla?\(([^)]+)\)/)
61
+ if (match) {
62
+ const parts = match[1].split(",").map(part => part.trim())
63
+ if (parts[3]) return parseFloat(parts[3])
64
+ }
65
+ }
66
+
67
+ if (normalizedColor.startsWith("#") && normalizedColor.length === 9) {
68
+ const alpha = parseInt(normalizedColor.slice(7, 9), 16)
69
+ return Math.round((alpha / 255) * 100) / 100
70
+ }
71
+
72
+ return 1
73
+ }
74
+
75
+ export function hsvToRgb(h, s, v) {
76
+ const normalizedH = h / 360
77
+ const normalizedS = s / 100
78
+ const normalizedV = v / 100
79
+
80
+ const i = Math.floor(normalizedH * 6)
81
+ const f = normalizedH * 6 - i
82
+ const p = normalizedV * (1 - normalizedS)
83
+ const q = normalizedV * (1 - f * normalizedS)
84
+ const t = normalizedV * (1 - (1 - f) * normalizedS)
85
+
86
+ let r
87
+ let g
88
+ let b
89
+
90
+ switch (i % 6) {
91
+ case 0: r = normalizedV; g = t; b = p; break
92
+ case 1: r = q; g = normalizedV; b = p; break
93
+ case 2: r = p; g = normalizedV; b = t; break
94
+ case 3: r = p; g = q; b = normalizedV; break
95
+ case 4: r = t; g = p; b = normalizedV; break
96
+ case 5: r = normalizedV; g = p; b = q; break
97
+ }
98
+
99
+ return {
100
+ r: Math.round(r * 255),
101
+ g: Math.round(g * 255),
102
+ b: Math.round(b * 255)
103
+ }
104
+ }
105
+
106
+ export function isValidColor(color) {
107
+ if (!color) return false
108
+
109
+ const normalizedColor = color.trim()
110
+
111
+ if (/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(normalizedColor)) return true
112
+ if (/^rgba?\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*(,\s*[\d.]+\s*)?\)$/.test(normalizedColor)) return true
113
+ if (/^hsla?\(\s*\d+\s*,\s*\d+%\s*,\s*\d+%\s*(,\s*[\d.]+\s*)?\)$/.test(normalizedColor)) return true
114
+ if (/^hsba?\(\s*\d+\s*,\s*\d+%\s*,\s*\d+%\s*(,\s*[\d.]+\s*)?\)$/.test(normalizedColor)) return true
115
+
116
+ return false
117
+ }
118
+
119
+ function rgbToHsv(r, g, b) {
120
+ const normalizedR = r / 255
121
+ const normalizedG = g / 255
122
+ const normalizedB = b / 255
123
+
124
+ const max = Math.max(normalizedR, normalizedG, normalizedB)
125
+ const min = Math.min(normalizedR, normalizedG, normalizedB)
126
+ const delta = max - min
127
+
128
+ let h = 0
129
+ const s = max === 0 ? 0 : delta / max
130
+ const v = max
131
+
132
+ if (delta !== 0) {
133
+ if (max === normalizedR) {
134
+ h = ((normalizedG - normalizedB) / delta + (normalizedG < normalizedB ? 6 : 0)) / 6
135
+ } else if (max === normalizedG) {
136
+ h = ((normalizedB - normalizedR) / delta + 2) / 6
137
+ } else {
138
+ h = ((normalizedR - normalizedG) / delta + 4) / 6
139
+ }
140
+ }
141
+
142
+ return {
143
+ h: Math.round(h * 360),
144
+ s: Math.round(s * 100),
145
+ v: Math.round(v * 100)
146
+ }
147
+ }
148
+
149
+ function hexToHsv(hex) {
150
+ const normalizedHex = hex.replace("#", "")
151
+
152
+ const r = parseInt(normalizedHex.slice(0, 2), 16)
153
+ const g = parseInt(normalizedHex.slice(2, 4), 16)
154
+ const b = parseInt(normalizedHex.slice(4, 6), 16)
155
+
156
+ return rgbToHsv(r, g, b)
157
+ }
158
+
159
+ function hsvToHex(h, s, v, alpha = 1, { disabledAlpha = false } = {}) {
160
+ const rgb = hsvToRgb(h, s, v)
161
+ const hex = `#${toHex(rgb.r)}${toHex(rgb.g)}${toHex(rgb.b)}`
162
+
163
+ if (alpha < 1 && !disabledAlpha) {
164
+ const alphaHex = toHex(Math.round(alpha * 255))
165
+ return `${hex}${alphaHex}`
166
+ }
167
+
168
+ return hex
169
+ }
170
+
171
+ function toHex(n) {
172
+ const hex = n.toString(16)
173
+ return hex.length === 1 ? "0" + hex : hex
174
+ }
175
+
176
+ function rgbStringToHsv(rgbString) {
177
+ const match = rgbString.match(/rgba?\(([^)]+)\)/)
178
+ if (!match) return defaultHsv()
179
+
180
+ const [r, g, b] = match[1].split(",").map(part => parseInt(part.trim()))
181
+ return rgbToHsv(r, g, b)
182
+ }
183
+
184
+ function hsvToRgbString(h, s, v, alpha = 1, { disabledAlpha = false } = {}) {
185
+ const rgb = hsvToRgb(h, s, v)
186
+
187
+ if (alpha < 1 && !disabledAlpha) {
188
+ return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha})`
189
+ }
190
+
191
+ return `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})`
192
+ }
193
+
194
+ function hslStringToHsv(hslString) {
195
+ const match = hslString.match(/hsla?\(([^)]+)\)/)
196
+ if (!match) return defaultHsv()
197
+
198
+ const parts = match[1].split(",").map(part => part.trim())
199
+ const h = parseFloat(parts[0])
200
+ const s = parseFloat(parts[1])
201
+ const l = parseFloat(parts[2])
202
+
203
+ return hslToHsv(h, s, l)
204
+ }
205
+
206
+ function hslToHsv(h, s, l) {
207
+ const normalizedS = s / 100
208
+ const normalizedL = l / 100
209
+
210
+ const v = normalizedL + normalizedS * Math.min(normalizedL, 1 - normalizedL)
211
+ const sv = v === 0 ? 0 : 2 * (1 - normalizedL / v)
212
+
213
+ return {
214
+ h: Math.round(h),
215
+ s: Math.round(sv * 100),
216
+ v: Math.round(v * 100)
217
+ }
218
+ }
219
+
220
+ function hsvToHsl(h, s, v) {
221
+ const normalizedS = s / 100
222
+ const normalizedV = v / 100
223
+
224
+ const l = normalizedV * (1 - normalizedS / 2)
225
+ const sl = l === 0 || l === 1 ? 0 : (normalizedV - l) / Math.min(l, 1 - l)
226
+
227
+ return {
228
+ h: Math.round(h),
229
+ s: Math.round(sl * 100),
230
+ l: Math.round(l * 100)
231
+ }
232
+ }
233
+
234
+ function hsvToHslString(h, s, v, alpha = 1, { disabledAlpha = false } = {}) {
235
+ const hsl = hsvToHsl(h, s, v)
236
+
237
+ if (alpha < 1 && !disabledAlpha) {
238
+ return `hsla(${hsl.h}, ${hsl.s}%, ${hsl.l}%, ${alpha})`
239
+ }
240
+
241
+ return `hsl(${hsl.h}, ${hsl.s}%, ${hsl.l}%)`
242
+ }
243
+
244
+ function hsbStringToHsv(hsbString) {
245
+ const match = hsbString.match(/hsba?\(([^)]+)\)/)
246
+ if (!match) return defaultHsv()
247
+
248
+ const parts = match[1].split(",").map(part => part.trim())
249
+ return {
250
+ h: Math.round(parseFloat(parts[0])),
251
+ s: Math.round(parseFloat(parts[1])),
252
+ v: Math.round(parseFloat(parts[2]))
253
+ }
254
+ }
255
+
256
+ function hsvToHsbString(h, s, v, alpha = 1, { disabledAlpha = false } = {}) {
257
+ if (alpha < 1 && !disabledAlpha) {
258
+ return `hsba(${h}, ${s}%, ${v}%, ${alpha})`
259
+ }
260
+
261
+ return `hsb(${h}, ${s}%, ${v}%)`
262
+ }
@@ -31,6 +31,15 @@ body {
31
31
  display: none !important;
32
32
  }
33
33
 
34
+ [data-hakumi-render-pending]:not([data-hakumi-ready="true"]) {
35
+ opacity: 0;
36
+ }
37
+
38
+ [data-hakumi-render-pending][data-hakumi-ready="true"] {
39
+ opacity: 1;
40
+ transition: opacity 0.15s ease;
41
+ }
42
+
34
43
  .hakumi-fade-enter,
35
44
  .hakumi-fade-appear {
36
45
  animation-duration: $transition-duration-base;
@@ -27,6 +27,7 @@
27
27
  @use "components/splitter";
28
28
  @use 'components/modal';
29
29
  @use 'components/drawer';
30
+ @use "components/form_item";
30
31
  @use "components/input";
31
32
  @use "components/input_number";
32
33
  @use "components/date_picker";
@@ -27,7 +27,7 @@
27
27
  .hakumi-breadcrumb-link {
28
28
  color: var(--color-text-secondary);
29
29
  text-decoration: none;
30
- transition: all 0.2s;
30
+ transition: all $transition-duration-base;
31
31
  }
32
32
 
33
33
  a.hakumi-breadcrumb-link {
@@ -63,7 +63,7 @@ a.hakumi-breadcrumb-link {
63
63
  padding: 2px 6px;
64
64
  border-radius: var(--border-radius-sm);
65
65
  cursor: pointer;
66
- transition: all 0.2s;
66
+ transition: all $transition-duration-base;
67
67
 
68
68
  &:hover {
69
69
  color: var(--color-text);
@@ -93,7 +93,7 @@
93
93
  margin: 0 4px;
94
94
  border-top: 2px solid transparent;
95
95
  border-radius: var(--border-radius);
96
- transition: background 0.2s;
96
+ transition: background $transition-duration-base;
97
97
  box-sizing: border-box;
98
98
 
99
99
  &:hover {
@@ -119,7 +119,7 @@
119
119
 
120
120
  .hakumi-calendar-cell-today .hakumi-calendar-date-value {
121
121
  background: var(--color-primary);
122
- color: #fff;
122
+ color: var(--color-text-inverse);
123
123
  border-radius: 50%;
124
124
  width: 24px;
125
125
  height: 24px;
@@ -138,7 +138,7 @@
138
138
  .hakumi-calendar-cell-range-start .hakumi-calendar-date-value,
139
139
  .hakumi-calendar-cell-range-end .hakumi-calendar-date-value {
140
140
  background: var(--color-primary);
141
- color: #fff;
141
+ color: var(--color-text-inverse);
142
142
  border-radius: 50%;
143
143
  width: 24px;
144
144
  height: 24px;
@@ -184,7 +184,7 @@
184
184
  height: 80px;
185
185
  padding: 8px 12px;
186
186
  border-radius: var(--border-radius);
187
- transition: background 0.2s;
187
+ transition: background $transition-duration-base;
188
188
  cursor: pointer;
189
189
 
190
190
  &:hover {
@@ -301,7 +301,7 @@
301
301
  line-height: 32px;
302
302
  border-radius: var(--border-radius);
303
303
  cursor: pointer;
304
- transition: all 0.2s;
304
+ transition: all $transition-duration-base;
305
305
 
306
306
  &:hover {
307
307
  background: var(--color-bg-spot);
@@ -318,7 +318,7 @@
318
318
 
319
319
  .hakumi-calendar-cell-selected .hakumi-calendar-date {
320
320
  background: var(--color-primary);
321
- color: #fff;
321
+ color: var(--color-text-inverse);
322
322
 
323
323
  &:hover {
324
324
  background: var(--color-primary-hover);
@@ -350,7 +350,7 @@
350
350
  justify-content: center;
351
351
  border-radius: var(--border-radius);
352
352
  cursor: pointer;
353
- transition: all 0.2s;
353
+ transition: all $transition-duration-base;
354
354
 
355
355
  &:hover {
356
356
  background: var(--color-bg-spot);
@@ -359,7 +359,7 @@
359
359
 
360
360
  .hakumi-calendar-cell-month.hakumi-calendar-cell-selected .hakumi-calendar-month-cell-inner {
361
361
  background: var(--color-primary);
362
- color: #fff;
362
+ color: var(--color-text-inverse);
363
363
  }
364
364
 
365
365
  .hakumi-calendar-month-value {
@@ -375,7 +375,7 @@
375
375
  .hakumi-calendar-cell-range-end {
376
376
  .hakumi-calendar-date {
377
377
  background: var(--color-primary);
378
- color: #fff;
378
+ color: var(--color-text-inverse);
379
379
 
380
380
  &:hover {
381
381
  background: var(--color-primary-hover);
@@ -494,7 +494,7 @@
494
494
  position: relative;
495
495
  cursor: pointer;
496
496
  color: var(--color-text);
497
- transition: background 0.2s, color 0.2s;
497
+ transition: background $transition-duration-base, color $transition-duration-base;
498
498
 
499
499
  &-in-view {
500
500
  color: var(--color-text);
@@ -547,7 +547,7 @@
547
547
  color: var(--color-text-tertiary);
548
548
  font-size: 12px;
549
549
  cursor: pointer;
550
- transition: background 0.2s, color 0.2s;
550
+ transition: background $transition-duration-base, color $transition-duration-base;
551
551
  }
552
552
 
553
553
  .hakumi-calendar-week-number {
@@ -644,7 +644,7 @@
644
644
  padding: 16px;
645
645
  border: 1px solid var(--color-border);
646
646
  border-radius: var(--border-radius-lg);
647
- transition: all 0.2s;
647
+ transition: all $transition-duration-base;
648
648
  cursor: pointer;
649
649
  display: flex;
650
650
  align-items: center;
@@ -699,7 +699,7 @@
699
699
  height: 60px;
700
700
  padding: 8px;
701
701
  border-radius: var(--border-radius);
702
- transition: all 0.2s;
702
+ transition: all $transition-duration-base;
703
703
  cursor: pointer;
704
704
  display: flex;
705
705
  align-items: center;
@@ -25,7 +25,7 @@
25
25
  background-color: var(--color-bg-container);
26
26
  border: 1px solid var(--color-border);
27
27
  border-radius: 6px;
28
- transition: all 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
28
+ transition: all $transition-duration-base $ease-in-out;
29
29
  width: 100%;
30
30
  height: 32px;
31
31
  padding: 0 30px 0 11px;
@@ -126,7 +126,7 @@
126
126
  margin-top: -6px;
127
127
  font-size: 12px;
128
128
  pointer-events: none;
129
- transition: transform 0.3s;
129
+ transition: transform $transition-duration-slow;
130
130
 
131
131
  .hakumi-cascader-open & {
132
132
  transform: rotate(180deg);
@@ -149,7 +149,7 @@
149
149
  background: var(--color-bg-container);
150
150
  cursor: pointer;
151
151
  opacity: 0;
152
- transition: color 0.3s ease, opacity 0.15s ease;
152
+ transition: color $transition-duration-slow ease, opacity 0.15s ease;
153
153
 
154
154
  &:hover {
155
155
  color: var(--color-text-tertiary);
@@ -173,7 +173,7 @@
173
173
  margin-top: 4px;
174
174
  background-color: var(--color-bg-elevated);
175
175
  border-radius: 8px;
176
- box-shadow: 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 9px 28px 8px rgba(0, 0, 0, 0.05);
176
+ box-shadow: var(--shadow-lg);
177
177
  display: flex;
178
178
  flex-direction: row;
179
179
  overflow: hidden;
@@ -217,7 +217,7 @@
217
217
  white-space: nowrap;
218
218
  text-overflow: ellipsis;
219
219
  cursor: pointer;
220
- transition: all 0.3s;
220
+ transition: all $transition-duration-slow;
221
221
  color: var(--color-text);
222
222
 
223
223
  &:hover {
@@ -78,15 +78,15 @@
78
78
  &::after {
79
79
  opacity: 1;
80
80
  transform: rotate(45deg) scale(1) translate(-50%, -50%);
81
- transition: all 0.2s cubic-bezier(0.12, 0.4, 0.29, 1.46) 0.1s;
81
+ transition: all $transition-duration-base cubic-bezier(0.12, 0.4, 0.29, 1.46) 0.1s;
82
82
  }
83
83
  }
84
84
  }
85
85
 
86
86
  &-indeterminate {
87
87
  .hakumi-checkbox-inner {
88
- background-color: #fff;
89
- border-color: #d9d9d9;
88
+ background-color: var(--color-bg-container);
89
+ border-color: var(--color-border);
90
90
 
91
91
  &::after {
92
92
  top: 50%;
@@ -153,7 +153,7 @@
153
153
  border: 1px solid var(--color-border);
154
154
  border-radius: var(--border-radius-sm);
155
155
  border-collapse: separate;
156
- transition: all 0.3s;
156
+ transition: all $transition-duration-slow;
157
157
 
158
158
  &:after {
159
159
  position: absolute;
@@ -162,7 +162,7 @@
162
162
  display: table;
163
163
  width: 5.7142857142857135px;
164
164
  height: 9.142857142857142px;
165
- border: 2px solid #fff;
165
+ border: 2px solid var(--color-text-inverse);
166
166
  border-top: 0;
167
167
  border-left: 0;
168
168
  transform: rotate(45deg) scale(0) translate(-50%, -50%);
@@ -197,20 +197,18 @@
197
197
  }
198
198
 
199
199
 
200
- [data-theme='dark'] {
200
+ [data-theme="dark"] {
201
201
  .hakumi-checkbox-inner {
202
202
  background-color: transparent;
203
203
  }
204
204
 
205
205
  .hakumi-checkbox-disabled {
206
206
  .hakumi-checkbox-inner {
207
- background-color: rgba(255, 255, 255, 0.08);
208
-
209
- border-color: #434343;
210
-
207
+ background-color: var(--color-fill-secondary);
208
+ border-color: var(--color-border);
211
209
 
212
210
  &::after {
213
- border-color: rgba(255, 255, 255, 0.25);
211
+ border-color: var(--color-disabled);
214
212
  }
215
213
  }
216
214
  }