@hyvor/design 2.1.19 → 2.1.20-beta.2

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.
@@ -13,6 +13,7 @@
13
13
  trigger?: Snippet;
14
14
  content?: Snippet;
15
15
  contentPadding?: number;
16
+ keepInDom?: boolean;
16
17
  }
17
18
 
18
19
  let {
@@ -24,18 +25,18 @@
24
25
  position = 'bottom',
25
26
  trigger,
26
27
  content,
27
- contentPadding
28
+ contentPadding,
29
+ keepInDom = false
28
30
  }: Props = $props();
29
31
 
30
32
  let triggerEl: HTMLElement | undefined = $state();
31
33
  </script>
32
34
 
33
35
  <span class="dropdown" class:relative>
36
+ <!-- svelte-ignore a11y_click_events_have_key_events, a11y_no_static_element_interactions -->
34
37
  <span
35
38
  class="trigger"
36
39
  onclick={() => (show = !show)}
37
- role="listbox"
38
- tabindex="0"
39
40
  onkeyup={(e) => {
40
41
  if (e.key === 'Escape') {
41
42
  show = false;
@@ -46,7 +47,7 @@
46
47
  {@render trigger?.()}
47
48
  </span>
48
49
 
49
- {#if show}
50
+ {#if show || keepInDom}
50
51
  <DropdownContent
51
52
  bind:show
52
53
  {width}
@@ -10,6 +10,7 @@ interface Props {
10
10
  trigger?: Snippet;
11
11
  content?: Snippet;
12
12
  contentPadding?: number;
13
+ keepInDom?: boolean;
13
14
  }
14
15
  declare const Dropdown: import("svelte").Component<Props, {}, "show">;
15
16
  type Dropdown = ReturnType<typeof Dropdown>;
@@ -101,6 +101,7 @@
101
101
  $effect(() => {
102
102
  position;
103
103
  align;
104
+ show;
104
105
  positionWrap();
105
106
  });
106
107
 
@@ -129,8 +130,9 @@
129
130
 
130
131
  <div
131
132
  class="content-wrap {align} {position}"
133
+ class:visually-hidden={!show}
132
134
  use:clickOutside={{
133
- enabled: closeOnOutsideClick,
135
+ enabled: closeOnOutsideClick && show,
134
136
  callback: () => (show = false)
135
137
  }}
136
138
  bind:this={contentWrap}
@@ -150,6 +152,10 @@
150
152
  flex-direction: column;
151
153
  }
152
154
 
155
+ .content-wrap.visually-hidden {
156
+ display: none;
157
+ }
158
+
153
159
  .content {
154
160
  overflow-y: auto;
155
161
  min-height: 0;
@@ -33,6 +33,7 @@
33
33
  let wrap: HTMLDivElement | undefined = $state();
34
34
  let tooltipEl: HTMLDivElement | undefined = $state();
35
35
  let showTimeout: ReturnType<typeof setTimeout>;
36
+ const tooltipId = $props.id();
36
37
 
37
38
  function positionTooltip() {
38
39
  if (wrap && tooltipEl && show) {
@@ -101,7 +102,7 @@
101
102
  class="tooltip-wrap {color}"
102
103
  onmouseenter={handleMouseEnter}
103
104
  onmouseleave={handleMouseLeave}
104
- role="tooltip"
105
+ aria-describedby={!disabled && show ? tooltipId : undefined}
105
106
  bind:this={wrap}
106
107
  {...wrapperProps}
107
108
  >
@@ -109,9 +110,11 @@
109
110
 
110
111
  {#if !disabled && show}
111
112
  <div
113
+ id={tooltipId}
112
114
  class="tooltip {position}"
113
115
  style:max-width={maxWidth + 'px'}
114
116
  bind:this={tooltipEl}
117
+ role="tooltip"
115
118
  transition:fade={{ duration: 100 }}
116
119
  >
117
120
  {#if tooltip}
@@ -5,6 +5,7 @@ interface Options {
5
5
  }
6
6
  type Input = Options | Function;
7
7
  export declare function clickOutside(node: HTMLElement, input: Input): {
8
+ update(newInput: Input): void;
8
9
  destroy(): void;
9
- } | undefined;
10
+ };
10
11
  export {};
@@ -1,8 +1,9 @@
1
+ function normalize(input) {
2
+ return typeof input === 'function' ? { callback: input } : input;
3
+ }
1
4
  export function clickOutside(node, input) {
2
- const options = typeof input === 'function' ? { callback: input } : input;
3
- const enabled = options.enabled === undefined ? true : options.enabled;
4
- if (!enabled)
5
- return;
5
+ let options = normalize(input);
6
+ let listening = false;
6
7
  const handleClick = (event) => {
7
8
  if (!node.contains(event.target)) {
8
9
  if (options.stopPropagation)
@@ -10,11 +11,28 @@ export function clickOutside(node, input) {
10
11
  options.callback();
11
12
  }
12
13
  };
13
- setTimeout(() => {
14
- document.addEventListener('click', handleClick);
15
- }, 0);
14
+ function sync() {
15
+ const enabled = options.enabled === undefined ? true : options.enabled;
16
+ if (enabled && !listening) {
17
+ listening = true;
18
+ setTimeout(() => {
19
+ if (listening)
20
+ document.addEventListener('click', handleClick);
21
+ }, 0);
22
+ }
23
+ else if (!enabled && listening) {
24
+ listening = false;
25
+ document.removeEventListener('click', handleClick);
26
+ }
27
+ }
28
+ sync();
16
29
  return {
30
+ update(newInput) {
31
+ options = normalize(newInput);
32
+ sync();
33
+ },
17
34
  destroy() {
35
+ listening = false;
18
36
  document.removeEventListener('click', handleClick);
19
37
  }
20
38
  };
package/dist/index.css CHANGED
@@ -1,4 +1,89 @@
1
- /* font */
1
+ /* <variables> */
2
+ :root {
3
+ /**
4
+ * Each app should have its own accent colors
5
+ * --accent should be usable with light text
6
+ * --accent-light and --accent-lightest should be usable with dark text
7
+ */
8
+ --accent: #000;
9
+ --accent-light: #bdbdbd;
10
+ --accent-lightest: #fafafa;
11
+ --accent-light-mid: #818181;
12
+ --accent-text: #fff;
13
+
14
+ --border: #e1e1e1;
15
+
16
+ --text: #000;
17
+ --text-light: #777;
18
+ --text-white: #fff;
19
+
20
+ /*
21
+ * Generally used colors
22
+ * In most cases, no need to extend these colors
23
+ */
24
+ --green-light: #cadfca;
25
+ --green: #4b874b;
26
+ --green-dark: #335c33;
27
+
28
+ --red-dark: #ab2525;
29
+ --red: #c05959;
30
+ --red-light: #ffdfdf;
31
+
32
+ --blue-dark: #334b81;
33
+ --blue: #5875b9;
34
+ --blue-light: #dae5ff;
35
+
36
+ --orange-dark: #8b5b04;
37
+ --orange: #a98526;
38
+ --orange-light: #efe3b4;
39
+
40
+ --gray-light: #ddd;
41
+ --gray: #999;
42
+ --gray-dark: #555;
43
+
44
+ --hover: #fafafa;
45
+ --hover-dark: #f0f0f0;
46
+
47
+ --link: #1d85d2;
48
+
49
+ --input: #f3f3f3;
50
+ --input-hover: #ccc;
51
+ /* checkbox/radio */
52
+
53
+ --box-shadow: 0 0 30px #0000000d;
54
+ --box-shadow-light: 0 0 10px 6px rgba(0, 0, 0, 0.06);
55
+ --box-radius: 20px;
56
+ --box-background: #fff;
57
+
58
+ --line-height-content: 28px;
59
+ --header-height: 55px;
60
+
61
+ --font-sans-serif: 'Readex Pro', Avenir, Inter, Helvetica, Arial, sans-serif;
62
+ --font-serif: 'Source Serif 4', serif;
63
+ }
64
+
65
+ :root.dark {
66
+ --background: #000;
67
+
68
+ --text: #fff;
69
+ --text-light: #999;
70
+ --box-background: #1c1c1c;
71
+
72
+ --accent-light: #555;
73
+ --accent-lightest: #2d2d2d;
74
+
75
+ --border: #4a4a4a;
76
+ --link: #7cb6e1;
77
+ --hover: #232323;
78
+
79
+ --input: #333;
80
+ }
81
+ /* </variables> */
82
+
83
+
84
+ /**
85
+ * Global styles
86
+ */
2
87
  :root {
3
88
  font-family: var(--font-sans-serif);
4
89
  font-size: 16px;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import './variables.css';
2
1
  import './index.css';
3
2
  import '@fontsource/readex-pro/400.css';
4
3
  import '@fontsource/readex-pro/600.css';
package/dist/index.js CHANGED
@@ -1,4 +1,3 @@
1
- import './variables.css';
2
1
  import './index.css';
3
2
  import '@fontsource/readex-pro/400.css';
4
3
  import '@fontsource/readex-pro/600.css';
@@ -28,15 +28,9 @@
28
28
  label?: string;
29
29
  title?: string;
30
30
  reviews: Review[];
31
- handwrittenNames?: boolean;
32
31
  }
33
32
 
34
- let {
35
- label = 'Testimonials',
36
- title = 'Loved by our customers.',
37
- reviews,
38
- handwrittenNames = true
39
- }: Props = $props();
33
+ let { label = 'Testimonials', title = 'Loved by our customers.', reviews }: Props = $props();
40
34
 
41
35
  let started: boolean[] = $state(reviews.map(() => false));
42
36
  let playing: boolean[] = $state(reviews.map(() => false));
@@ -132,12 +126,6 @@
132
126
  }
133
127
  </script>
134
128
 
135
- <svelte:head>
136
- {#if handwrittenNames}
137
- <link href="https://fonts.bunny.net/css?family=caveat:600,700" rel="stylesheet" />
138
- {/if}
139
- </svelte:head>
140
-
141
129
  {#snippet meta(review: Review)}
142
130
  <div class="role">
143
131
  {review.role}, <br />
@@ -156,7 +144,7 @@
156
144
  </div>
157
145
  {/snippet}
158
146
 
159
- <section class="hds-testimonials" class:handwritten={handwrittenNames}>
147
+ <section class="hds-testimonials">
160
148
  <div class="hds-container head">
161
149
  <p class="label">{label}</p>
162
150
  <h2>{@html title}</h2>
@@ -426,24 +414,16 @@
426
414
  }
427
415
 
428
416
  .name {
429
- font-size: 16px;
417
+ font-size: 18px;
430
418
  font-weight: 600;
431
419
  color: var(--text);
432
420
  line-height: 1.3;
433
421
  }
434
422
 
435
- .handwritten .name {
436
- font-family: 'Caveat', cursive;
437
- font-size: 28px;
438
- font-weight: 600;
439
- line-height: 1.15;
440
- }
441
-
442
423
  .role {
443
424
  font-size: 14px;
444
425
  line-height: 1.35;
445
426
  color: var(--text-light);
446
- margin-top: 4px;
447
427
  font-family: var(--font-serif);
448
428
  }
449
429
 
@@ -460,10 +440,6 @@
460
440
  text-decoration: underline;
461
441
  }
462
442
 
463
- .handwritten .company {
464
- font-weight: 600;
465
- }
466
-
467
443
  .video-card {
468
444
  overflow: hidden;
469
445
  padding: 0;
@@ -24,7 +24,6 @@ interface Props {
24
24
  label?: string;
25
25
  title?: string;
26
26
  reviews: Review[];
27
- handwrittenNames?: boolean;
28
27
  }
29
28
  declare const Testimonials: import("svelte").Component<Props, {}, "">;
30
29
  type Testimonials = ReturnType<typeof Testimonials>;
package/package.json CHANGED
@@ -1,8 +1,13 @@
1
1
  {
2
2
  "name": "@hyvor/design",
3
- "version": "2.1.19",
3
+ "version": "2.1.20-beta.2",
4
4
  "license": "MIT",
5
5
  "private": false,
6
+ "sideEffects": [
7
+ "./dist/index.js",
8
+ "./dist/index.css",
9
+ "**/*.css"
10
+ ],
6
11
  "repository": {
7
12
  "url": "https://github.com/hyvor/design"
8
13
  },
@@ -1,80 +0,0 @@
1
- /* variables */
2
- :root {
3
- /**
4
- * Each app should have its own accent colors
5
- * --accent should be usable with light text
6
- * --accent-light and --accent-lightest should be usable with dark text
7
- */
8
- --accent: #000;
9
- --accent-light: #bdbdbd;
10
- --accent-lightest: #fafafa;
11
- --accent-light-mid: #818181;
12
- --accent-text: #fff;
13
-
14
- --border: #e1e1e1;
15
-
16
- --text: #000;
17
- --text-light: #777;
18
- --text-white: #fff;
19
-
20
- /*
21
- * Generally used colors
22
- * In most cases, no need to extend these colors
23
- */
24
- --green-light: #cadfca;
25
- --green: #4b874b;
26
- --green-dark: #335c33;
27
-
28
- --red-dark: #ab2525;
29
- --red: #c05959;
30
- --red-light: #ffdfdf;
31
-
32
- --blue-dark: #334b81;
33
- --blue: #5875b9;
34
- --blue-light: #dae5ff;
35
-
36
- --orange-dark: #8b5b04;
37
- --orange: #a98526;
38
- --orange-light: #efe3b4;
39
-
40
- --gray-light: #ddd;
41
- --gray: #999;
42
- --gray-dark: #555;
43
-
44
- --hover: #fafafa;
45
- --hover-dark: #f0f0f0;
46
-
47
- --link: #1d85d2;
48
-
49
- --input: #f3f3f3;
50
- --input-hover: #ccc;
51
- /* checkbox/radio */
52
-
53
- --box-shadow: 0 0 30px #0000000d;
54
- --box-shadow-light: 0 0 10px 6px rgba(0, 0, 0, 0.06);
55
- --box-radius: 20px;
56
- --box-background: #fff;
57
-
58
- --line-height-content: 28px;
59
- --header-height: 55px;
60
-
61
- --font-sans-serif: 'Readex Pro', Avenir, Inter, Helvetica, Arial, sans-serif;
62
- --font-serif: 'Source Serif 4', serif;
63
- }
64
-
65
- :root.dark {
66
- --background: #000;
67
-
68
- --text: #fff;
69
- --text-light: #999;
70
- --box-background: #1c1c1c;
71
-
72
- --accent-light: #555;
73
- --accent-lightest: #2d2d2d;
74
-
75
- --border: #4a4a4a;
76
- --link: #7cb6e1;
77
- --hover: #232323;
78
-
79
- --input: #333;
80
- }