lapikit 0.7.2 → 0.7.4

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 (73) hide show
  1. package/dist/@types/components.d.ts +1 -7
  2. package/dist/@types/dom.d.ts +4 -3
  3. package/dist/@types/props.d.ts +3 -3
  4. package/dist/animations/ripple.js +33 -17
  5. package/dist/components/accordion/accordion.svelte +192 -228
  6. package/dist/components/accordion/accordion.types.d.ts +5 -7
  7. package/dist/components/accordion/modules/accordion-item.svelte +144 -140
  8. package/dist/components/alert/alert.svelte +246 -293
  9. package/dist/components/alert/alert.types.d.ts +5 -5
  10. package/dist/components/app/app.svelte +29 -44
  11. package/dist/components/appbar/appbar.svelte +205 -190
  12. package/dist/components/appbar/appbar.types.d.ts +6 -6
  13. package/dist/components/aspect-ratio/aspect-ratio.svelte +43 -63
  14. package/dist/components/avatar/avatar.svelte +169 -161
  15. package/dist/components/avatar/avatar.types.d.ts +3 -4
  16. package/dist/components/btn/btn.svelte +431 -465
  17. package/dist/components/btn/btn.types.d.ts +5 -6
  18. package/dist/components/card/card.svelte +214 -176
  19. package/dist/components/card/card.types.d.ts +6 -3
  20. package/dist/components/card/modules/card-actions.svelte +11 -35
  21. package/dist/components/card/modules/card-container.svelte +9 -33
  22. package/dist/components/card/modules/card-content.svelte +18 -44
  23. package/dist/components/card/modules/card-media.svelte +10 -34
  24. package/dist/components/card/modules/card-title.svelte +22 -48
  25. package/dist/components/chip/chip.svelte +416 -464
  26. package/dist/components/chip/chip.types.d.ts +5 -5
  27. package/dist/components/dialog/dialog.svelte +174 -171
  28. package/dist/components/dialog/dialog.types.d.ts +6 -6
  29. package/dist/components/dropdown/dropdown.svelte +149 -144
  30. package/dist/components/dropdown/dropdown.types.d.ts +4 -11
  31. package/dist/components/field/field.svelte +474 -0
  32. package/dist/components/field/field.svelte.d.ts +4 -0
  33. package/dist/components/field/field.types.d.ts +46 -0
  34. package/dist/components/field/field.types.js +1 -0
  35. package/dist/components/icon/icon.svelte +67 -96
  36. package/dist/components/icon/icon.types.d.ts +2 -1
  37. package/dist/components/index.d.ts +2 -0
  38. package/dist/components/index.js +1 -0
  39. package/dist/components/list/list.svelte +193 -194
  40. package/dist/components/list/list.types.d.ts +5 -7
  41. package/dist/components/list/modules/list-item.svelte +134 -147
  42. package/dist/components/modal/modal.svelte +239 -222
  43. package/dist/components/modal/modal.types.d.ts +6 -6
  44. package/dist/components/popover/popover.svelte +125 -127
  45. package/dist/components/popover/popover.types.d.ts +4 -11
  46. package/dist/components/separator/separator.svelte +56 -87
  47. package/dist/components/separator/separator.types.d.ts +1 -1
  48. package/dist/components/spacer/spacer.svelte +6 -25
  49. package/dist/components/textfield/textfield.svelte +94 -543
  50. package/dist/components/textfield/textfield.types.d.ts +13 -33
  51. package/dist/components/toolbar/toolbar.svelte +216 -211
  52. package/dist/components/toolbar/toolbar.types.d.ts +8 -9
  53. package/dist/components/tooltip/tooltip.svelte +201 -266
  54. package/dist/components/tooltip/tooltip.types.d.ts +3 -10
  55. package/dist/constants.js +1 -0
  56. package/dist/html-mapped.d.ts +1 -15
  57. package/dist/html-mapped.js +0 -19
  58. package/dist/labs/sheet/sheet.svelte +145 -19
  59. package/dist/labs/sheet/sheet.svelte.d.ts +2 -10
  60. package/dist/labs/sheet/sheet.types.d.ts +16 -0
  61. package/dist/labs/sheet/sheet.types.js +1 -0
  62. package/dist/utils/color.d.ts +2 -2
  63. package/dist/utils/color.js +2 -1
  64. package/dist/utils/components.d.ts +10 -10
  65. package/dist/utils/components.js +16 -75
  66. package/dist/utils/floating.d.ts +58 -0
  67. package/dist/utils/floating.js +131 -0
  68. package/dist/utils/index.d.ts +1 -0
  69. package/dist/utils/index.js +1 -0
  70. package/package.json +3 -3
  71. package/dist/components/dropdown/dropdown.svelte.js +0 -148
  72. package/dist/components/popover/popover.svelte.js +0 -134
  73. package/dist/components/tooltip/tooltip.svelte.js +0 -131
@@ -1,8 +1,12 @@
1
1
  <script lang="ts">
2
2
  import { onDestroy } from 'svelte';
3
- import { useClassName, useStyles, clickOutside, useElevation } from '../../utils';
4
- import { makeComponentProps } from '../../html-mapped';
5
- import { getPositions } from './dropdown.svelte.js';
3
+ import {
4
+ clickOutside,
5
+ floating,
6
+ useComponentAttrs,
7
+ useElevation,
8
+ type FloatingAnchor
9
+ } from '../../utils';
6
10
  import type { DropdownProps, ModelDropdownProps } from './dropdown.types.js';
7
11
 
8
12
  let {
@@ -14,68 +18,37 @@
14
18
  closeOnClick = false,
15
19
  openOnHover = false,
16
20
  color,
17
- background,
18
21
  density = 'default',
19
- class: className = '',
20
- style: styleAttr = '',
22
+ class: className,
23
+ style: styleAttr,
21
24
  's-class': sClass,
22
25
  's-style': sStyle,
23
26
  elevation,
24
27
  ...rest
25
28
  }: DropdownProps = $props();
26
29
 
27
- let { classProps, styleProps, restProps } = $derived(
28
- makeComponentProps(rest as Record<string, unknown>)
30
+ let attrs = $derived(
31
+ useComponentAttrs('kit-dropdown-content', { className, sClass, styleAttr, sStyle, color }, rest)
29
32
  );
30
-
31
33
  let elevationState = $derived(useElevation(elevation));
32
34
 
33
- let componentClass = $derived(
34
- useClassName({
35
- baseClass: 'kit-dropdown-content',
36
- className: `${className ?? ''}`.trim(),
37
- sClass,
38
- classProps
39
- })
40
- );
41
-
42
- let componentStyle = $derived(
43
- useStyles({
44
- styleAttr,
45
- sStyle,
46
- styleProps
47
- })
48
- );
49
-
50
- let resolvedStyle = $derived(
51
- [
52
- componentStyle,
53
- color ? `--kit-dropdown-fg:${color && `var(--kit-color-${color})`}` : '',
54
- background ? `--kit-dropdown-bg:${background && `var(--kit-color-${background})`}` : ''
55
- ]
56
- .filter(Boolean)
57
- .join('; ')
58
- );
59
-
60
- const positioner = getPositions();
61
-
62
35
  let contentRef = $state<HTMLElement | null>(null);
63
36
  let activatorRef = $state<HTMLElement | PointerEvent | null>(null);
64
37
  let open = $state(false);
65
- let axis = $state(positioner.values);
66
- let timeoutId = $state<ReturnType<typeof setTimeout> | null>(null);
38
+ let timeoutId: ReturnType<typeof setTimeout> | null = null;
39
+
40
+ // a pointer event opens the menu at the position of the pointer (context menu)
41
+ let anchor = $derived<FloatingAnchor | null>(
42
+ activatorRef instanceof HTMLElement
43
+ ? activatorRef
44
+ : activatorRef
45
+ ? { x: activatorRef.clientX, y: activatorRef.clientY }
46
+ : null
47
+ );
67
48
 
68
49
  const clearHoverTimeout = () => {
69
- if (timeoutId) {
70
- clearTimeout(timeoutId);
71
- timeoutId = null;
72
- }
73
- };
74
-
75
- const updatePosition = () => {
76
- if (!contentRef || !activatorRef) return;
77
- positioner.update(activatorRef, contentRef, position, false, true);
78
- axis = positioner.values;
50
+ if (timeoutId) clearTimeout(timeoutId);
51
+ timeoutId = null;
79
52
  };
80
53
 
81
54
  const handleToggle = (element: HTMLElement | PointerEvent | null) => {
@@ -89,10 +62,6 @@
89
62
  open = false;
90
63
  };
91
64
 
92
- const handleContentClick = () => {
93
- if (closeOnClick && open) open = false;
94
- };
95
-
96
65
  const handleMouseEvent = (
97
66
  state: 'open' | 'close',
98
67
  element: HTMLElement | PointerEvent | null
@@ -112,41 +81,30 @@
112
81
  }, 150);
113
82
  };
114
83
 
115
- let model: ModelDropdownProps = {
84
+ const model: ModelDropdownProps = {
116
85
  get open() {
117
86
  return open;
118
87
  },
119
- close: () => handleClose(),
120
- toggle: (element) => handleToggle(element)
88
+ close: handleClose,
89
+ toggle: handleToggle
121
90
  };
122
91
 
123
92
  $effect(() => {
124
- if (open && contentRef && activatorRef) {
125
- updatePosition();
126
- }
93
+ ref = contentRef;
127
94
  });
128
95
 
129
96
  $effect(() => {
130
97
  if (!open) return;
131
98
 
132
- const close = () => (open = false);
133
-
134
- window.addEventListener('scroll', close, { passive: true });
135
- window.addEventListener('resize', updatePosition);
136
-
137
- return () => {
138
- window.removeEventListener('scroll', close);
139
- window.removeEventListener('resize', updatePosition);
99
+ const onKeydown = (event: KeyboardEvent) => {
100
+ if (event.key === 'Escape') handleClose();
140
101
  };
141
- });
142
102
 
143
- $effect(() => {
144
- ref = contentRef;
103
+ document.addEventListener('keydown', onKeydown);
104
+ return () => document.removeEventListener('keydown', onKeydown);
145
105
  });
146
106
 
147
- onDestroy(() => {
148
- clearHoverTimeout();
149
- });
107
+ onDestroy(clearHoverTimeout);
150
108
  </script>
151
109
 
152
110
  {@render activator?.(model, (state, element) => handleMouseEvent(state, element))}
@@ -154,87 +112,134 @@
154
112
  {#if open}
155
113
  <div
156
114
  bind:this={contentRef}
157
- class={componentClass}
158
- style={`left:${axis.x}px; top:${axis.y}px; ${resolvedStyle}`}
115
+ popover="manual"
116
+ class={attrs.class}
117
+ style={attrs.style}
159
118
  role="menu"
160
119
  data-rounded={rounded}
161
- data-position={axis.location ?? position}
162
120
  data-density={density}
121
+ data-elevation={elevationState.base}
122
+ data-elevation-hover={elevationState.hover}
123
+ data-elevation-active={elevationState.active}
163
124
  onmouseover={() => handleMouseEvent('open', activatorRef)}
164
125
  onmouseleave={() => handleMouseEvent('close', activatorRef)}
165
126
  onclick={(event) => {
166
127
  event.stopPropagation();
167
- handleContentClick();
128
+ if (closeOnClick) handleClose();
168
129
  }}
169
- data-elevation={elevationState.base}
170
- data-elevation-hover={elevationState.hover}
171
- data-elevation-active={elevationState.active}
130
+ use:floating={{ anchor, side: position, offset: 0 }}
172
131
  use:clickOutside={{ exclude: [contentRef, activatorRef], onClose: handleClose }}
173
- {...restProps}
132
+ {...attrs.rest}
174
133
  >
175
134
  {@render children?.()}
176
135
  </div>
177
136
  {/if}
178
137
 
179
- <style>
180
- .kit-dropdown-content {
181
- --kit-dropdown-bg: var(--kit-color-surface-3);
182
- --kit-dropdown-fg: var(--kit-color-text);
183
-
184
- position: fixed;
185
- z-index: 1800;
186
- min-width: 12rem;
187
- max-width: min(22rem, calc(100vw - 1rem));
188
- padding: calc(var(--kit-space-default) + var(--kit-dropdown-density-offset) / 2);
189
- border: 0;
190
- border-radius: var(--kit-dropdown-radius);
191
- background: var(--kit-dropdown-bg);
192
- color: var(--kit-dropdown-fg);
193
- transform-origin: top left;
194
- animation: kit-dropdown-enter 140ms ease;
195
- }
196
-
197
- /**
198
- * rounded
199
- * @link ...
200
- */
201
- .kit-dropdown-content[data-rounded='0'] {
202
- --kit-dropdown-radius: var(--kit-shape-none);
203
- }
204
- .kit-dropdown-content[data-rounded='xs'] {
205
- --kit-dropdown-radius: var(--kit-shape-xs);
206
- }
207
- .kit-dropdown-content[data-rounded='sm'] {
208
- --kit-dropdown-radius: var(--kit-shape-sm);
209
- }
210
- .kit-dropdown-content[data-rounded='md'] {
211
- --kit-dropdown-radius: var(--kit-shape-md);
212
- }
213
- .kit-dropdown-content[data-rounded='lg'] {
214
- --kit-dropdown-radius: var(--kit-shape-lg);
215
- }
216
- .kit-dropdown-content[data-rounded='xl'] {
217
- --kit-dropdown-radius: var(--kit-shape-xl);
218
- }
219
-
220
- /**
221
- * density
222
- * @link no url
223
- */
224
- .kit-dropdown-content[data-density='compact'] {
225
- --kit-dropdown-density-offset: var(--kit-density-compact);
226
- }
227
- .kit-dropdown-content[data-density='default'] {
228
- --kit-dropdown-density-offset: var(--kit-density-default);
229
- }
230
- .kit-dropdown-content[data-density='comfortable'] {
231
- --kit-dropdown-density-offset: var(--kit-density-comfortable);
232
- }
233
-
234
- @keyframes kit-dropdown-enter {
235
- from {
236
- opacity: 0;
237
- scale: 0.98;
238
- }
239
- }
240
- </style>
138
+ <style>:where(.kit-dropdown-content) {
139
+ --kit-dropdown-content-color: initial;
140
+ --kit-dropdown-content-on-color: initial;
141
+ --kit-dropdown-content-active-fg: initial;
142
+ --kit-dropdown-content-active-shade: initial;
143
+ --kit-dropdown-content-hover-fg: initial;
144
+ --kit-dropdown-content-pressed-fg: initial;
145
+ --kit-dropdown-content-bg: var(--kit-dropdown-content-color, var(--kit-color-surface-3));
146
+ --kit-dropdown-content-fg: var(--kit-dropdown-content-on-color, var(--kit-dropdown-content-contrast, var(--kit-color-text)));
147
+ --kit-dropdown-content-ink: var(--kit-dropdown-content-color, var(--kit-color-text));
148
+ --kit-dropdown-content-hover: color-mix(in oklab, var(--kit-dropdown-content-bg), var(--kit-dropdown-content-fg) 8%);
149
+ --kit-dropdown-content-pressed: color-mix(in oklab, var(--kit-dropdown-content-bg), var(--kit-dropdown-content-fg) 14%);
150
+ --kit-dropdown-content-soft: color-mix(in oklab, var(--kit-dropdown-content-bg) 16%, transparent);
151
+ --kit-dropdown-content-border: color-mix(in oklab, var(--kit-dropdown-content-bg), var(--kit-dropdown-content-fg) 20%);
152
+ --kit-dropdown-content-active: color-mix(
153
+ in oklab,
154
+ var(--kit-dropdown-content-color),
155
+ var(--kit-dropdown-content-fg) var(--kit-dropdown-content-active-shade, 14%)
156
+ );
157
+ }
158
+ @supports (color: color(from red srgb-linear r g b)) {
159
+ :where(.kit-dropdown-content) {
160
+ --kit-dropdown-content-contrast: color(from var(--kit-dropdown-content-color) srgb-linear clamp(0, (0.1791 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) * 100000, 1) clamp(0, (0.1791 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) * 100000, 1) clamp(0, (0.1791 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) * 100000, 1)/1);
161
+ }
162
+ }
163
+
164
+ .kit-dropdown-content {
165
+ position: fixed;
166
+ inset: auto;
167
+ z-index: 1800;
168
+ box-sizing: border-box;
169
+ min-width: 12rem;
170
+ max-width: min(22rem, 100vw - 1rem);
171
+ margin: 0;
172
+ padding: calc(var(--kit-space-default) + var(--kit-dropdown-content-density-offset) / 2);
173
+ overflow: visible;
174
+ border: 0;
175
+ border-radius: var(--kit-dropdown-content-radius);
176
+ background-color: var(--kit-dropdown-content-bg);
177
+ color: var(--kit-dropdown-content-fg);
178
+ transform-origin: top left;
179
+ animation: kit-dropdown-enter 140ms ease;
180
+ }
181
+ .kit-dropdown-content[data-side=top] {
182
+ transform-origin: bottom left;
183
+ }
184
+
185
+ @keyframes kit-dropdown-enter {
186
+ from {
187
+ opacity: 0;
188
+ scale: 0.98;
189
+ }
190
+ }
191
+ /**
192
+ * rounded
193
+ * @link https://lapikit.dev/docs/customize
194
+ */
195
+ :where(.kit-dropdown-content[data-rounded="0"]) {
196
+ --kit-dropdown-content-radius: var(--kit-shape-none);
197
+ }
198
+
199
+ :where(.kit-dropdown-content[data-rounded=xs]) {
200
+ --kit-dropdown-content-radius: var(--kit-shape-xs);
201
+ }
202
+
203
+ :where(.kit-dropdown-content[data-rounded=sm]) {
204
+ --kit-dropdown-content-radius: var(--kit-shape-sm);
205
+ }
206
+
207
+ :where(.kit-dropdown-content[data-rounded=md]) {
208
+ --kit-dropdown-content-radius: var(--kit-shape-md);
209
+ }
210
+
211
+ :where(.kit-dropdown-content[data-rounded=lg]) {
212
+ --kit-dropdown-content-radius: var(--kit-shape-lg);
213
+ }
214
+
215
+ :where(.kit-dropdown-content[data-rounded=xl]) {
216
+ --kit-dropdown-content-radius: var(--kit-shape-xl);
217
+ }
218
+
219
+ :where(.kit-dropdown-content[data-rounded=full]) {
220
+ --kit-dropdown-content-radius: var(--kit-shape-full);
221
+ }
222
+
223
+ /**
224
+ * density
225
+ * @link https://lapikit.dev/docs/components/dropdown#density
226
+ */
227
+ :where(.kit-dropdown-content[data-density=dense]) {
228
+ --kit-dropdown-content-density-offset: var(--kit-density-dense);
229
+ }
230
+
231
+ :where(.kit-dropdown-content[data-density=compact]) {
232
+ --kit-dropdown-content-density-offset: var(--kit-density-compact);
233
+ }
234
+
235
+ :where(.kit-dropdown-content[data-density=default]) {
236
+ --kit-dropdown-content-density-offset: var(--kit-density-default);
237
+ }
238
+
239
+ :where(.kit-dropdown-content[data-density=comfortable]) {
240
+ --kit-dropdown-content-density-offset: var(--kit-density-comfortable);
241
+ }
242
+
243
+ :where(.kit-dropdown-content[data-density=spacious]) {
244
+ --kit-dropdown-content-density-offset: var(--kit-density-spacious);
245
+ }</style>
@@ -1,10 +1,5 @@
1
- import type { Component, DensityType, ElevationProps, PropValue, RoundedType } from '../../@types/index';
1
+ import type { ColorProps, Component, ElevationProps, RoundedType } from '../../@types/index';
2
2
  import type { Snippet } from 'svelte';
3
- export type PositionElement = {
4
- x: number;
5
- y: number;
6
- location: 'top' | 'bottom' | 'left' | 'right' | null;
7
- };
8
3
  export type ModelDropdownProps = {
9
4
  open: boolean;
10
5
  close: () => void;
@@ -13,17 +8,15 @@ export type ModelDropdownProps = {
13
8
  export type ModelDropdownHandleProps = (state: 'open' | 'close', element: HTMLElement | PointerEvent | null) => void;
14
9
  export interface DropdownProps extends Component {
15
10
  ref?: HTMLElement | null;
16
- rounded?: RoundedType;
11
+ rounded?: RoundedType | 'full';
17
12
  position?: 'top' | 'bottom' | 'left' | 'right';
18
13
  openOnHover?: boolean;
19
14
  closeOnClick?: boolean;
20
- color?: string;
21
- background?: string;
22
- density?: DensityType;
15
+ color?: ColorProps;
16
+ density?: 'dense' | 'compact' | 'default' | 'comfortable' | 'spacious';
23
17
  activator?: Snippet<[
24
18
  ModelDropdownProps,
25
19
  (state: 'open' | 'close', element: HTMLElement | PointerEvent | null) => void
26
20
  ]>;
27
- [key: string]: PropValue | Record<string, PropValue> | unknown;
28
21
  elevation?: ElevationProps;
29
22
  }