@wtfalch/design 0.1.0

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 (75) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +147 -0
  3. package/dist/components/Brand.d.ts +10 -0
  4. package/dist/components/Brand.js +212 -0
  5. package/dist/components/Button.d.ts +63 -0
  6. package/dist/components/Button.js +74 -0
  7. package/dist/components/Callout.d.ts +37 -0
  8. package/dist/components/Callout.js +71 -0
  9. package/dist/components/Card.d.ts +42 -0
  10. package/dist/components/Card.js +30 -0
  11. package/dist/components/Checkbox.d.ts +32 -0
  12. package/dist/components/Checkbox.js +31 -0
  13. package/dist/components/DangerZone.d.ts +59 -0
  14. package/dist/components/DangerZone.js +50 -0
  15. package/dist/components/Dialog.d.ts +28 -0
  16. package/dist/components/Dialog.js +29 -0
  17. package/dist/components/Empty.d.ts +45 -0
  18. package/dist/components/Empty.js +35 -0
  19. package/dist/components/Field.d.ts +58 -0
  20. package/dist/components/Field.js +46 -0
  21. package/dist/components/Icon.d.ts +64 -0
  22. package/dist/components/Icon.js +235 -0
  23. package/dist/components/Illustration.d.ts +36 -0
  24. package/dist/components/Illustration.js +48 -0
  25. package/dist/components/Input.d.ts +14 -0
  26. package/dist/components/Input.js +65 -0
  27. package/dist/components/Markdown.d.ts +21 -0
  28. package/dist/components/Markdown.js +29 -0
  29. package/dist/components/Modal.d.ts +59 -0
  30. package/dist/components/Modal.js +72 -0
  31. package/dist/components/Pill.d.ts +40 -0
  32. package/dist/components/Pill.js +41 -0
  33. package/dist/components/Progress.d.ts +35 -0
  34. package/dist/components/Progress.js +27 -0
  35. package/dist/components/Rows.d.ts +101 -0
  36. package/dist/components/Rows.js +55 -0
  37. package/dist/components/Select.d.ts +28 -0
  38. package/dist/components/Select.js +56 -0
  39. package/dist/components/SizeGrid.d.ts +34 -0
  40. package/dist/components/SizeGrid.js +41 -0
  41. package/dist/components/Skeleton.d.ts +45 -0
  42. package/dist/components/Skeleton.js +47 -0
  43. package/dist/components/Slider.d.ts +70 -0
  44. package/dist/components/Slider.js +100 -0
  45. package/dist/components/Table.d.ts +43 -0
  46. package/dist/components/Table.js +13 -0
  47. package/dist/components/Tabs.d.ts +72 -0
  48. package/dist/components/Tabs.js +82 -0
  49. package/dist/components/Textarea.d.ts +9 -0
  50. package/dist/components/Textarea.js +22 -0
  51. package/dist/components/Toast.d.ts +43 -0
  52. package/dist/components/Toast.js +78 -0
  53. package/dist/components/Toggle.d.ts +56 -0
  54. package/dist/components/Toggle.js +189 -0
  55. package/dist/components/Tooltip.d.ts +22 -0
  56. package/dist/components/Tooltip.js +62 -0
  57. package/dist/components/Tour.d.ts +33 -0
  58. package/dist/components/Tour.js +108 -0
  59. package/dist/components/iconNames.d.ts +18 -0
  60. package/dist/components/iconNames.js +60 -0
  61. package/dist/components/tourMarker.d.ts +29 -0
  62. package/dist/components/tourMarker.js +58 -0
  63. package/dist/contrast.d.ts +18 -0
  64. package/dist/contrast.js +27 -0
  65. package/dist/hooks/useTrapFocus.d.ts +24 -0
  66. package/dist/hooks/useTrapFocus.js +67 -0
  67. package/dist/illustrations.d.ts +11 -0
  68. package/dist/illustrations.js +55 -0
  69. package/dist/index.d.ts +72 -0
  70. package/dist/index.js +65 -0
  71. package/dist/styles/index.css +3124 -0
  72. package/dist/themes.d.ts +210 -0
  73. package/dist/themes.js +300 -0
  74. package/dist/tokens.css +251 -0
  75. package/package.json +74 -0
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Keep focus inside a window, and put it back when the window goes away.
3
+ *
4
+ * `Modal` uses this, and so does anything that is modal without being shaped
5
+ * like a modal -- the applet studio is a full-screen workspace with its own
6
+ * header and its own idea of what closing means, and wrapping it in `Modal` to
7
+ * borrow the behaviour would mean pretending it is a dialog with a title and a
8
+ * footer. It is not. It just has the same obligation.
9
+ *
10
+ * **The obligation.** Everything behind a modal stays in the tab order:
11
+ * focusable, operable by keyboard, and invisible under the scrim. Tab past the
12
+ * last control and you are somewhere on the page you cannot see, pressing
13
+ * buttons you cannot read. No mouse ever finds this, which is why every one of
14
+ * the app's eight modals shipped without it.
15
+ */
16
+ import { useCallback, useEffect } from 'react';
17
+ const FOCUSABLE = 'button:not([disabled]), [href], input:not([disabled]),' +
18
+ ' select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
19
+ export function useTrapFocus(box, { active = true, onEscape, } = {}) {
20
+ const focusables = useCallback(() => [...(box.current?.querySelectorAll(FOCUSABLE) ?? [])]
21
+ // A control inside a collapsed section is in the DOM and not on screen.
22
+ .filter((el) => el.offsetParent !== null || el === document.activeElement), [box]);
23
+ useEffect(() => {
24
+ if (!active)
25
+ return;
26
+ const cameFrom = document.activeElement;
27
+ // Only if nothing inside has claimed it already: several of these windows
28
+ // put `autoFocus` on the field you came here to edit, which is a better
29
+ // landing place than the box.
30
+ if (!box.current?.contains(document.activeElement))
31
+ box.current?.focus();
32
+ return () => {
33
+ // Back to the control that opened it. Without this, focus falls to the
34
+ // top of the document and a keyboard user starts the page again.
35
+ const back = cameFrom;
36
+ if (back?.isConnected)
37
+ back.focus?.();
38
+ };
39
+ }, [active, box]);
40
+ return useCallback((e) => {
41
+ if (!active)
42
+ return;
43
+ if (e.key === 'Escape' && onEscape) {
44
+ // Stopped here so a window inside a window closes one layer, not both.
45
+ e.stopPropagation();
46
+ onEscape();
47
+ return;
48
+ }
49
+ if (e.key !== 'Tab')
50
+ return;
51
+ const items = focusables();
52
+ if (!items.length)
53
+ return;
54
+ const first = items[0];
55
+ const last = items[items.length - 1];
56
+ const here = document.activeElement;
57
+ if (e.shiftKey && (here === first || here === box.current)) {
58
+ e.preventDefault();
59
+ last.focus();
60
+ }
61
+ else if (!e.shiftKey && here === last) {
62
+ e.preventDefault();
63
+ first.focus();
64
+ }
65
+ }, [active, box, focusables, onEscape]);
66
+ }
67
+ export default useTrapFocus;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * The art, inlined.
3
+ *
4
+ * ~240 KB of SVG, which is most of this package's weight — so it lives in its
5
+ * own module referenced only by `Illustration`. A bundler that tree-shakes the
6
+ * component away drops the art with it, and an app that never draws an empty
7
+ * state never pays for one.
8
+ */
9
+ export declare const ILLUSTRATIONS: readonly ["alien", "alsoarrg", "alsonote", "alsositting", "arrgh", "chill", "cycling", "hah", "happystab", "idk", "moustache", "note", "psychoticstab", "really", "righton", "sitting", "uhm", "vibes", "weird", "what", "wow"];
10
+ export type IllustrationName = (typeof ILLUSTRATIONS)[number];
11
+ export declare const ILLUSTRATION_SVG: Record<IllustrationName, string>;