@zerodev/react-ui 0.0.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 (48) hide show
  1. package/README.md +89 -0
  2. package/dist/_types/components/Badge/index.d.ts +10 -0
  3. package/dist/_types/components/Badge/index.d.ts.map +1 -0
  4. package/dist/_types/components/Button/index.d.ts +10 -0
  5. package/dist/_types/components/Button/index.d.ts.map +1 -0
  6. package/dist/_types/components/Callout/index.d.ts +6 -0
  7. package/dist/_types/components/Callout/index.d.ts.map +1 -0
  8. package/dist/_types/components/Icon/index.d.ts +9 -0
  9. package/dist/_types/components/Icon/index.d.ts.map +1 -0
  10. package/dist/_types/components/IconButton/index.d.ts +7 -0
  11. package/dist/_types/components/IconButton/index.d.ts.map +1 -0
  12. package/dist/_types/components/Input/index.d.ts +13 -0
  13. package/dist/_types/components/Input/index.d.ts.map +1 -0
  14. package/dist/_types/components/ListItem/index.d.ts +23 -0
  15. package/dist/_types/components/ListItem/index.d.ts.map +1 -0
  16. package/dist/_types/components/Switch/index.d.ts +6 -0
  17. package/dist/_types/components/Switch/index.d.ts.map +1 -0
  18. package/dist/_types/components/Text/index.d.ts +8 -0
  19. package/dist/_types/components/Text/index.d.ts.map +1 -0
  20. package/dist/_types/components/WrappedPressable/index.d.ts +7 -0
  21. package/dist/_types/components/WrappedPressable/index.d.ts.map +1 -0
  22. package/dist/_types/components/Wrapper/index.d.ts +7 -0
  23. package/dist/_types/components/Wrapper/index.d.ts.map +1 -0
  24. package/dist/_types/index.d.ts +17 -0
  25. package/dist/_types/index.d.ts.map +1 -0
  26. package/dist/_types/utils/common.d.ts +3 -0
  27. package/dist/_types/utils/common.d.ts.map +1 -0
  28. package/dist/index.cjs +2 -0
  29. package/dist/index.cjs.map +1 -0
  30. package/dist/index.mjs +3751 -0
  31. package/dist/index.mjs.map +1 -0
  32. package/dist/styles.css +2 -0
  33. package/package.json +84 -0
  34. package/src/components/Badge/index.tsx +45 -0
  35. package/src/components/Button/index.tsx +81 -0
  36. package/src/components/Callout/index.tsx +23 -0
  37. package/src/components/Icon/index.tsx +43 -0
  38. package/src/components/IconButton/index.tsx +24 -0
  39. package/src/components/Input/index.tsx +147 -0
  40. package/src/components/ListItem/index.tsx +136 -0
  41. package/src/components/Switch/index.tsx +35 -0
  42. package/src/components/Text/index.tsx +20 -0
  43. package/src/components/WrappedPressable/index.tsx +46 -0
  44. package/src/components/Wrapper/index.tsx +43 -0
  45. package/src/index.ts +33 -0
  46. package/src/svg.d.ts +6 -0
  47. package/src/utils/common.ts +17 -0
  48. package/tailwind.config.ts +58 -0
@@ -0,0 +1,2 @@
1
+ /*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial}}}@layer theme{:root,:host{--zd-font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--zd-color-gray-700:oklch(37.3% .034 259.733);--zd-color-gray-900:oklch(21% .034 264.665);--zd-color-white:#fff;--zd-spacing:.25rem;--zd-text-sm--line-height:calc(1.25 / .875);--zd-text-base--line-height:calc(1.5 / 1);--zd-text-lg--line-height:calc(1.75 / 1.125);--zd-text-2xl--line-height:calc(2 / 1.5);--zd-font-weight-medium:500;--zd-font-weight-semibold:600;--zd-font-weight-bold:700;--zd-radius-lg:.5rem;--zd-radius-xl:.75rem;--zd-radius-2xl:1rem;--zd-radius-3xl:1.5rem;--zd-animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--zd-default-transition-duration:.15s;--zd-default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--zd-default-font-family:sans-serif;--zd-default-mono-font-family:var(--zd-font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--zd-default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--zd-default-font-feature-settings,normal);font-variation-settings:var(--zd-default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--zd-default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--zd-default-mono-font-feature-settings,normal);font-variation-settings:var(--zd-default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.zd\:pointer-events-none{pointer-events:none}.zd\:absolute{position:absolute}.zd\:relative{position:relative}.zd\:inset-0{inset:calc(var(--zd-spacing) * 0)}.zd\:mb-2{margin-bottom:calc(var(--zd-spacing) * 2)}.zd\:flex{display:flex}.zd\:grid{display:grid}.zd\:h-2\.5{height:calc(var(--zd-spacing) * 2.5)}.zd\:h-3{height:calc(var(--zd-spacing) * 3)}.zd\:h-3\.5{height:calc(var(--zd-spacing) * 3.5)}.zd\:h-5{height:calc(var(--zd-spacing) * 5)}.zd\:h-6{height:calc(var(--zd-spacing) * 6)}.zd\:h-7{height:calc(var(--zd-spacing) * 7)}.zd\:h-11{height:calc(var(--zd-spacing) * 11)}.zd\:h-12{height:calc(var(--zd-spacing) * 12)}.zd\:h-13{height:52px}.zd\:h-16{height:calc(var(--zd-spacing) * 16)}.zd\:h-32{height:calc(var(--zd-spacing) * 32)}.zd\:h-\[52px\]{height:52px}.zd\:h-\[68px\]{height:68px}.zd\:h-full{height:100%}.zd\:min-h-11{min-height:calc(var(--zd-spacing) * 11)}.zd\:min-h-\[300px\]{min-height:300px}.zd\:w-2\.5{width:calc(var(--zd-spacing) * 2.5)}.zd\:w-3{width:calc(var(--zd-spacing) * 3)}.zd\:w-3\.5{width:calc(var(--zd-spacing) * 3.5)}.zd\:w-5{width:calc(var(--zd-spacing) * 5)}.zd\:w-6{width:calc(var(--zd-spacing) * 6)}.zd\:w-13{width:52px}.zd\:w-14{width:calc(var(--zd-spacing) * 14)}.zd\:w-72{width:calc(var(--zd-spacing) * 72)}.zd\:w-80{width:calc(var(--zd-spacing) * 80)}.zd\:w-\[52px\]{width:52px}.zd\:w-full{width:100%}.zd\:min-w-0{min-width:calc(var(--zd-spacing) * 0)}.zd\:min-w-\[400px\]{min-width:400px}.zd\:flex-1{flex:1}.zd\:shrink-0{flex-shrink:0}.zd\:animate-pulse{animation:var(--zd-animate-pulse)}.zd\:cursor-not-allowed{cursor:not-allowed}.zd\:cursor-pointer{cursor:pointer}.zd\:resize-none{resize:none}.zd\:flex-col{flex-direction:column}.zd\:flex-row{flex-direction:row}.zd\:flex-wrap{flex-wrap:wrap}.zd\:place-items-center{place-items:center}.zd\:items-center{align-items:center}.zd\:justify-between{justify-content:space-between}.zd\:justify-center{justify-content:center}.zd\:gap-1{gap:calc(var(--zd-spacing) * 1)}.zd\:gap-1\.5{gap:calc(var(--zd-spacing) * 1.5)}.zd\:gap-2{gap:calc(var(--zd-spacing) * 2)}.zd\:gap-3{gap:calc(var(--zd-spacing) * 3)}.zd\:gap-4{gap:calc(var(--zd-spacing) * 4)}.zd\:self-end{align-self:flex-end}.zd\:self-start{align-self:flex-start}.zd\:overflow-hidden{overflow:hidden}.zd\:rounded-2xl{border-radius:var(--zd-radius-2xl)}.zd\:rounded-3xl{border-radius:var(--zd-radius-3xl)}.zd\:rounded-full{border-radius:3.40282e38px}.zd\:rounded-lg{border-radius:var(--zd-radius-lg)}.zd\:rounded-xl{border-radius:var(--zd-radius-xl)}.zd\:border-0{border-style:var(--tw-border-style);border-width:0}.zd\:border-\[0\.3px\]{border-style:var(--tw-border-style);border-width:.3px}.zd\:border-offWhite{border-color:#f7f5f0}.zd\:border-white\/0{border-color:var(--zd-color-white)}@supports (color:color-mix(in lab, red, red)){.zd\:border-white\/0{border-color:color-mix(in oklab, var(--zd-color-white) 0%, transparent)}}.zd\:bg-greyScale\/30{background-color:oklab(16.9052% .00636494 .00836386/.3)}.zd\:bg-offWhite\/50{background-color:oklab(97.0302% .000165075 .00696582/.5)}.zd\:bg-orange\/10{background-color:oklab(70.9342% .114827 .116983/.1)}.zd\:bg-solarOrange{background-color:#e76000}.zd\:bg-solarOrange\/15{background-color:oklab(65.138% .131584 .131685/.15)}.zd\:bg-transparent{background-color:#0000}.zd\:bg-white,.zd\:bg-white\/20{background-color:var(--zd-color-white)}@supports (color:color-mix(in lab, red, red)){.zd\:bg-white\/20{background-color:color-mix(in oklab, var(--zd-color-white) 20%, transparent)}}.zd\:bg-white\/40{background-color:var(--zd-color-white)}@supports (color:color-mix(in lab, red, red)){.zd\:bg-white\/40{background-color:color-mix(in oklab, var(--zd-color-white) 40%, transparent)}}.zd\:bg-white\/70{background-color:var(--zd-color-white)}@supports (color:color-mix(in lab, red, red)){.zd\:bg-white\/70{background-color:color-mix(in oklab, var(--zd-color-white) 70%, transparent)}}.zd\:p-1{padding:calc(var(--zd-spacing) * 1)}.zd\:p-2{padding:calc(var(--zd-spacing) * 2)}.zd\:p-4{padding:calc(var(--zd-spacing) * 4)}.zd\:p-6{padding:calc(var(--zd-spacing) * 6)}.zd\:px-0{padding-inline:calc(var(--zd-spacing) * 0)}.zd\:px-2{padding-inline:calc(var(--zd-spacing) * 2)}.zd\:px-4{padding-inline:calc(var(--zd-spacing) * 4)}.zd\:px-5{padding-inline:calc(var(--zd-spacing) * 5)}.zd\:px-6{padding-inline:calc(var(--zd-spacing) * 6)}.zd\:py-1{padding-block:calc(var(--zd-spacing) * 1)}.zd\:py-3{padding-block:calc(var(--zd-spacing) * 3)}.zd\:py-3\.5{padding-block:calc(var(--zd-spacing) * 3.5)}.zd\:py-5{padding-block:calc(var(--zd-spacing) * 5)}.zd\:pr-1{padding-right:calc(var(--zd-spacing) * 1)}.zd\:pr-2{padding-right:calc(var(--zd-spacing) * 2)}.zd\:pl-2{padding-left:calc(var(--zd-spacing) * 2)}.zd\:pl-4{padding-left:calc(var(--zd-spacing) * 4)}.zd\:text-left{text-align:left}.zd\:font-roboto{font-family:Roboto,sans-serif}.zd\:font-sans{font-family:sans-serif}.zd\:text-2xl{font-size:20px;line-height:var(--tw-leading,var(--zd-text-2xl--line-height))}.zd\:text-base{font-size:14px;line-height:var(--tw-leading,var(--zd-text-base--line-height))}.zd\:text-body1{font-size:16px;line-height:var(--tw-leading,130%)}.zd\:text-body2{font-size:14px;line-height:var(--tw-leading,130%)}.zd\:text-body3{font-size:12px;line-height:var(--tw-leading,130%)}.zd\:text-body4{font-size:10px;line-height:var(--tw-leading,130%)}.zd\:text-h1{font-size:42px;line-height:var(--tw-leading,110%)}.zd\:text-h2{font-size:28px;line-height:var(--tw-leading,110%)}.zd\:text-h3{font-size:18px;line-height:var(--tw-leading,130%)}.zd\:text-lg{font-size:16px;line-height:var(--tw-leading,var(--zd-text-lg--line-height))}.zd\:text-sm{font-size:12px;line-height:var(--tw-leading,var(--zd-text-sm--line-height))}.zd\:font-bold{--tw-font-weight:var(--zd-font-weight-bold);font-weight:var(--zd-font-weight-bold)}.zd\:font-medium{--tw-font-weight:var(--zd-font-weight-medium);font-weight:var(--zd-font-weight-medium)}.zd\:font-semibold{--tw-font-weight:var(--zd-font-weight-semibold);font-weight:var(--zd-font-weight-semibold)}.zd\:break-all{word-break:break-all}.zd\:text-gray-700{color:var(--zd-color-gray-700)}.zd\:text-gray-900{color:var(--zd-color-gray-900)}.zd\:text-greyScale{color:#130e0b}.zd\:text-greyScale\/50{color:oklab(16.9052% .00636494 .00836386/.5)}.zd\:text-greyScale\/90{color:oklab(16.9052% .00636494 .00836386/.9)}.zd\:text-orange{color:#f27b3e}.zd\:text-solarOrange{color:#e76000}.zd\:text-white{color:var(--zd-color-white)}.zd\:caret-gray-900{caret-color:var(--zd-color-gray-900)}.zd\:opacity-50{opacity:.5}.zd\:shadow-\[inset_0_-4px_4px_0_rgba\(255\,255\,255\,0\.10\)\,inset_0_3px_4px_0_rgba\(0\,0\,0\,0\.02\)\]{--tw-shadow:inset 0 -4px 4px 0 var(--tw-shadow-color,#ffffff1a), inset 0 3px 4px 0 var(--tw-shadow-color,#00000005);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.zd\:shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.zd\:backdrop-blur-\[15px\]{--tw-backdrop-blur:blur(15px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.zd\:transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--zd-default-transition-timing-function));transition-duration:var(--tw-duration,var(--zd-default-transition-duration))}.zd\:outline-none{--tw-outline-style:none;outline-style:none}.zd\:placeholder\:text-gray-900\/50::placeholder{color:var(--zd-color-gray-900)}@supports (color:color-mix(in lab, red, red)){.zd\:placeholder\:text-gray-900\/50::placeholder{color:color-mix(in oklab, var(--zd-color-gray-900) 50%, transparent)}}@media (hover:hover){.zd\:hover\:bg-white\/5:hover{background-color:var(--zd-color-white)}@supports (color:color-mix(in lab, red, red)){.zd\:hover\:bg-white\/5:hover{background-color:color-mix(in oklab, var(--zd-color-white) 5%, transparent)}}.zd\:hover\:bg-white\/20:hover{background-color:var(--zd-color-white)}@supports (color:color-mix(in lab, red, red)){.zd\:hover\:bg-white\/20:hover{background-color:color-mix(in oklab, var(--zd-color-white) 20%, transparent)}}}.zd\:active\:bg-white\/10:active{background-color:var(--zd-color-white)}@supports (color:color-mix(in lab, red, red)){.zd\:active\:bg-white\/10:active{background-color:color-mix(in oklab, var(--zd-color-white) 10%, transparent)}}.zd\:active\:bg-white\/30:active{background-color:var(--zd-color-white)}@supports (color:color-mix(in lab, red, red)){.zd\:active\:bg-white\/30:active{background-color:color-mix(in oklab, var(--zd-color-white) 30%, transparent)}}}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@keyframes pulse{50%{opacity:.5}}
package/package.json ADDED
@@ -0,0 +1,84 @@
1
+ {
2
+ "name": "@zerodev/react-ui",
3
+ "version": "0.0.1",
4
+ "description": "React UI primitives for ZeroDev",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/zerodevapp/zerodev-wallet-sdk.git",
8
+ "directory": "packages/react-ui"
9
+ },
10
+ "sideEffects": [
11
+ "**/*.css"
12
+ ],
13
+ "main": "./dist/index.cjs",
14
+ "module": "./dist/index.mjs",
15
+ "types": "./dist/_types/index.d.ts",
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/_types/index.d.ts",
19
+ "import": "./dist/index.mjs",
20
+ "require": "./dist/index.cjs"
21
+ },
22
+ "./styles.css": "./dist/styles.css"
23
+ },
24
+ "files": [
25
+ "dist",
26
+ "tailwind.config.ts",
27
+ "src/**/*.ts",
28
+ "src/**/*.tsx",
29
+ "!dist/**/*.tsbuildinfo",
30
+ "!.env",
31
+ "!src/**/*.test.ts",
32
+ "!src/**/*.test.tsx",
33
+ "!src/**/*.stories.ts",
34
+ "!src/**/*.stories.tsx",
35
+ "!.changeset"
36
+ ],
37
+ "keywords": [
38
+ "react",
39
+ "components",
40
+ "ui",
41
+ "primitives",
42
+ "zerodev"
43
+ ],
44
+ "peerDependencies": {
45
+ "react": "^18.0.0 || ^19.0.0"
46
+ },
47
+ "devDependencies": {
48
+ "@storybook/addon-a11y": "^10.3.3",
49
+ "@storybook/addon-docs": "^10.3.3",
50
+ "@storybook/react-vite": "^10.3.3",
51
+ "@tailwindcss/cli": "^4.2.2",
52
+ "@tailwindcss/postcss": "^4.2.2",
53
+ "@testing-library/react": "^16.3.0",
54
+ "@types/react": "^19",
55
+ "@types/react-dom": "^19",
56
+ "@vitejs/plugin-react": "^4.7.0",
57
+ "postcss": "^8.5.10",
58
+ "react": "19.2.0",
59
+ "react-dom": "19.2.0",
60
+ "storybook": "^10.3.3",
61
+ "tailwindcss": "^4.2.2",
62
+ "typescript": "5.9.3",
63
+ "vite": "^6.4.1",
64
+ "vite-plugin-svgr": "5.0.0"
65
+ },
66
+ "dependencies": {
67
+ "clsx": "^2.1.1",
68
+ "tailwind-merge": "^3.5.0"
69
+ },
70
+ "scripts": {
71
+ "build": "pnpm run clean && pnpm run build:css && pnpm run build:js && pnpm run build:types",
72
+ "build:css": "npx @tailwindcss/cli -i ./src/styles.css -o ./dist/styles.css --minify",
73
+ "build:js": "vite build",
74
+ "build:types": "tsc --project ./tsconfig.build.json --outDir ./dist/_types --emitDeclarationOnly --declaration --declarationMap",
75
+ "dev": "tsc --watch",
76
+ "dev:css": "npx @tailwindcss/cli -i ./src/styles.css -o ./dist/styles.css --watch",
77
+ "typecheck": "tsc --noEmit --project ./tsconfig.build.json",
78
+ "clean": "rm -rf dist",
79
+ "storybook": "storybook dev -p 6006",
80
+ "build-storybook": "storybook build",
81
+ "test": "vitest run",
82
+ "test:watch": "vitest"
83
+ }
84
+ }
@@ -0,0 +1,45 @@
1
+ import { cn } from '../../utils/common'
2
+ import { Icon, type IconName } from '../Icon'
3
+ import { Text } from '../Text'
4
+
5
+ export interface BadgeProps {
6
+ text: string
7
+ variant?: 'primary' | 'secondary'
8
+ leadingIcon?: IconName
9
+ trailingIcon?: IconName
10
+ className?: string
11
+ }
12
+
13
+ const variantStyles = {
14
+ primary: 'zd:bg-white/40',
15
+ secondary: 'zd:bg-orange/10',
16
+ }
17
+
18
+ export function Badge({
19
+ text,
20
+ variant = 'primary',
21
+ leadingIcon,
22
+ trailingIcon,
23
+ className,
24
+ }: BadgeProps) {
25
+ return (
26
+ <div
27
+ className={cn(
28
+ 'zd:py-1 zd:px-2 zd:gap-1 zd:flex zd:flex-row zd:items-center zd:rounded-lg zd:self-start',
29
+ variantStyles[variant],
30
+ className,
31
+ )}
32
+ >
33
+ {leadingIcon && (
34
+ <Icon
35
+ name={leadingIcon}
36
+ className="zd:w-3 zd:h-3 zd:text-solarOrange"
37
+ />
38
+ )}
39
+ <Text className="zd:text-body3">{text}</Text>
40
+ {trailingIcon && (
41
+ <Icon name={trailingIcon} className="zd:w-2.5 zd:h-2.5" />
42
+ )}
43
+ </div>
44
+ )
45
+ }
@@ -0,0 +1,81 @@
1
+ import type { ButtonHTMLAttributes, CSSProperties } from 'react'
2
+
3
+ import { cn } from '../../utils/common'
4
+ import { Icon, type IconName } from '../Icon'
5
+ import { Text } from '../Text'
6
+ import { Wrapper } from '../Wrapper'
7
+
8
+ // The frosted surface (white@0.5 bg, 0.3px border, 15px blur) comes from Wrapper.
9
+ // Button layers on top of it the Figma button spec: 24px radius, a transparent
10
+ // border (overriding Wrapper's offWhite stroke), and the "blur effect" inset
11
+ // shadows. Per-variant colour + hover/active live on the inner <button>.
12
+ const surfaceClass =
13
+ 'zd:rounded-3xl zd:border-white/0 ' +
14
+ 'zd:shadow-[inset_0_-4px_4px_0_rgba(255,255,255,0.10),inset_0_3px_4px_0_rgba(0,0,0,0.02)]'
15
+
16
+ const innerClass =
17
+ 'zd:flex zd:items-center zd:justify-center zd:gap-2 zd:h-16 zd:w-full zd:px-5 zd:py-3.5 zd:cursor-pointer zd:transition-colors'
18
+
19
+ // secondary keeps Wrapper's white@0.5 surface; primary overrides it with a dark
20
+ // translucent fill (via inline style, since Wrapper sets its bg inline). Hover/
21
+ // active tints sit on the inner button.
22
+ const bgClasses: Record<NonNullable<ButtonProps['action']>, string> = {
23
+ primary: 'zd:hover:bg-white/5 zd:active:bg-white/10',
24
+ secondary: 'zd:hover:bg-white/20 zd:active:bg-white/30',
25
+ }
26
+
27
+ const primaryStyle: CSSProperties = {
28
+ backgroundColor: 'rgba(19, 14, 11, 0.9)',
29
+ }
30
+
31
+ const textClasses: Record<NonNullable<ButtonProps['action']>, string> = {
32
+ primary: 'zd:text-white zd:text-body1',
33
+ secondary: 'zd:text-greyScale zd:text-body1',
34
+ }
35
+
36
+ export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
37
+ text?: string
38
+ iconName?: IconName
39
+ action?: 'primary' | 'secondary'
40
+ trailIcon?: boolean
41
+ }
42
+
43
+ export function Button({
44
+ text,
45
+ className,
46
+ iconName,
47
+ trailIcon,
48
+ disabled,
49
+ action = 'primary',
50
+ ...rest
51
+ }: ButtonProps) {
52
+ return (
53
+ <Wrapper
54
+ className={cn(surfaceClass, { 'zd:opacity-50': disabled }, className)}
55
+ {...(action === 'primary' && { style: primaryStyle })}
56
+ >
57
+ <button
58
+ type={rest.type ?? 'button'}
59
+ className={cn(innerClass, bgClasses[action], {
60
+ 'zd:cursor-not-allowed': disabled,
61
+ })}
62
+ disabled={disabled}
63
+ {...rest}
64
+ >
65
+ {iconName && !trailIcon && (
66
+ <Icon
67
+ name={iconName}
68
+ className={cn('zd:w-6 zd:h-6', textClasses[action])}
69
+ />
70
+ )}
71
+ {text && <Text className={textClasses[action]}>{text}</Text>}
72
+ {iconName && trailIcon && (
73
+ <Icon
74
+ name={iconName}
75
+ className={cn('zd:w-6 zd:h-6', textClasses[action])}
76
+ />
77
+ )}
78
+ </button>
79
+ </Wrapper>
80
+ )
81
+ }
@@ -0,0 +1,23 @@
1
+ import { Icon } from '../Icon'
2
+ import { Text } from '../Text'
3
+ import { Wrapper } from '../Wrapper'
4
+
5
+ export interface CalloutProps {
6
+ title: string
7
+ description: string
8
+ }
9
+
10
+ export function Callout({ title, description }: CalloutProps) {
11
+ return (
12
+ <Wrapper
13
+ className="zd:w-full zd:py-5 zd:px-4 zd:flex zd:flex-col zd:gap-4 zd:rounded-xl"
14
+ variant="solid"
15
+ >
16
+ <div className="zd:flex zd:flex-row zd:items-center zd:gap-2">
17
+ <Icon name="info" className="zd:h-3.5 zd:w-3.5 zd:text-solarOrange" />
18
+ <Text className="zd:text-body1">{title}</Text>
19
+ </div>
20
+ <Text className="zd:text-body3 zd:break-all">{description}</Text>
21
+ </Wrapper>
22
+ )
23
+ }
@@ -0,0 +1,43 @@
1
+ import type { FC, SVGProps } from 'react'
2
+ import { cn } from '../../utils/common'
3
+
4
+ type SvgModule = { default: FC<SVGProps<SVGSVGElement>> }
5
+
6
+ // Eagerly import every .svg from assets/icons/ as a React component
7
+ const svgModules = import.meta.glob('../../../assets/icons/*.svg', {
8
+ eager: true,
9
+ query: '?react',
10
+ }) as Record<string, SvgModule>
11
+
12
+ // Build a name → component map: "check" → check component, "arrow-left" → arrowLeft component
13
+ function toCamelCase(str: string) {
14
+ const parts = str.split('-')
15
+ return (
16
+ parts[0] +
17
+ parts
18
+ .slice(1)
19
+ .map((s) => s.charAt(0).toUpperCase() + s.slice(1))
20
+ .join('')
21
+ )
22
+ }
23
+
24
+ const icons: Record<string, FC<SVGProps<SVGSVGElement>>> = {}
25
+ for (const [path, mod] of Object.entries(svgModules) as [string, SvgModule][]) {
26
+ const filename = path.split('/').pop()?.replace('.svg', '') ?? ''
27
+ const name = toCamelCase(filename)
28
+ icons[name] = mod.default
29
+ }
30
+
31
+ export { icons }
32
+
33
+ export type IconName = keyof typeof icons
34
+
35
+ export interface IconProps extends SVGProps<SVGSVGElement> {
36
+ name: IconName
37
+ }
38
+
39
+ export function Icon({ name, className, ...props }: IconProps) {
40
+ const Component = icons[name]
41
+ if (!Component) return null
42
+ return <Component className={cn('zd:text-greyScale', className)} {...props} />
43
+ }
@@ -0,0 +1,24 @@
1
+ import type { ButtonHTMLAttributes } from 'react'
2
+
3
+ import { cn } from '../../utils/common'
4
+ import { Icon, type IconName } from '../Icon'
5
+ import { Wrapper } from '../Wrapper'
6
+
7
+ export interface IconButtonProps
8
+ extends ButtonHTMLAttributes<HTMLButtonElement> {
9
+ iconName: IconName
10
+ }
11
+
12
+ export function IconButton({ iconName, className, ...rest }: IconButtonProps) {
13
+ return (
14
+ <Wrapper className={cn('zd:h-13 zd:w-13 zd:rounded-2xl', className)}>
15
+ <button
16
+ type="button"
17
+ className="zd:flex zd:items-center zd:justify-center zd:flex-1 zd:h-full zd:w-full zd:cursor-pointer zd:hover:bg-white/20 zd:active:bg-white/30 zd:transition-colors"
18
+ {...rest}
19
+ >
20
+ <Icon name={iconName} className="zd:h-6 zd:w-6 zd:text-greyScale" />
21
+ </button>
22
+ </Wrapper>
23
+ )
24
+ }
@@ -0,0 +1,147 @@
1
+ import {
2
+ type InputHTMLAttributes,
3
+ type TextareaHTMLAttributes,
4
+ useState,
5
+ } from 'react'
6
+
7
+ import { cn } from '../../utils/common'
8
+ import { Icon, type IconName } from '../Icon'
9
+ import { Wrapper } from '../Wrapper'
10
+
11
+ type Variant = 'default' | 'ghost' | 'listItemStyle'
12
+
13
+ export interface InputProps
14
+ extends Omit<InputHTMLAttributes<HTMLInputElement>, 'children'> {
15
+ variant?: Variant
16
+ multiline?: boolean
17
+ iconName?: IconName
18
+ children?: React.ReactNode
19
+ containerClassName?: string
20
+ }
21
+
22
+ function getHeightClass(multiline: boolean | undefined, variant: Variant) {
23
+ if (multiline) return 'zd:h-32 zd:py-3'
24
+ if (variant === 'listItemStyle') return 'zd:h-[68px]'
25
+ return 'zd:h-11'
26
+ }
27
+
28
+ function InputIcon({
29
+ variant,
30
+ iconName,
31
+ }: {
32
+ variant: Variant
33
+ iconName: IconName
34
+ }) {
35
+ if (variant === 'listItemStyle') {
36
+ return (
37
+ <div className="zd:w-13 zd:h-13 zd:shrink-0 zd:bg-white zd:rounded-2xl zd:flex zd:items-center zd:justify-center">
38
+ <Icon name={iconName} className="zd:w-6 zd:h-6 zd:text-greyScale" />
39
+ </div>
40
+ )
41
+ }
42
+ return (
43
+ <Icon
44
+ name={iconName}
45
+ className="zd:w-5 zd:h-5 zd:shrink-0 zd:text-greyScale/50"
46
+ />
47
+ )
48
+ }
49
+
50
+ // `min-w-0` is required so the input doesn't claim its intrinsic content
51
+ // width on mobile browsers (Chrome on Android most visibly), which would
52
+ // squash the leading icon and the trailing chevron-button child.
53
+ const baseInputClass =
54
+ 'zd:flex-1 zd:min-w-0 zd:px-0 zd:text-gray-900 zd:font-medium zd:outline-none zd:bg-transparent zd:min-h-11 zd:placeholder:text-gray-900/50 zd:caret-gray-900'
55
+
56
+ export function Input({
57
+ variant = 'default',
58
+ multiline,
59
+ iconName,
60
+ children,
61
+ className,
62
+ containerClassName,
63
+ onFocus,
64
+ onBlur,
65
+ ...inputProps
66
+ }: InputProps) {
67
+ const [isFocused, setIsFocused] = useState(false)
68
+
69
+ const handleFocus = (
70
+ e: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement>,
71
+ ) => {
72
+ setIsFocused(true)
73
+ onFocus?.(e as React.FocusEvent<HTMLInputElement>)
74
+ }
75
+
76
+ const handleBlur = (
77
+ e: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement>,
78
+ ) => {
79
+ setIsFocused(false)
80
+ onBlur?.(e as React.FocusEvent<HTMLInputElement>)
81
+ }
82
+
83
+ const inputElement = multiline ? (
84
+ <textarea
85
+ {...(inputProps as unknown as TextareaHTMLAttributes<HTMLTextAreaElement>)}
86
+ onFocus={handleFocus}
87
+ onBlur={handleBlur}
88
+ className={cn(baseInputClass, 'zd:resize-none zd:h-full', className)}
89
+ />
90
+ ) : (
91
+ <input
92
+ {...inputProps}
93
+ onFocus={handleFocus}
94
+ onBlur={handleBlur}
95
+ className={cn(baseInputClass, 'zd:h-full', className)}
96
+ />
97
+ )
98
+
99
+ if (variant === 'ghost') {
100
+ return multiline ? (
101
+ <textarea
102
+ {...(inputProps as unknown as TextareaHTMLAttributes<HTMLTextAreaElement>)}
103
+ onFocus={
104
+ onFocus as TextareaHTMLAttributes<HTMLTextAreaElement>['onFocus']
105
+ }
106
+ onBlur={onBlur as TextareaHTMLAttributes<HTMLTextAreaElement>['onBlur']}
107
+ className={cn(
108
+ baseInputClass,
109
+ 'zd:w-full zd:pl-4 zd:pr-2 zd:resize-none',
110
+ className,
111
+ )}
112
+ />
113
+ ) : (
114
+ <input
115
+ {...inputProps}
116
+ onFocus={onFocus}
117
+ onBlur={onBlur}
118
+ className={cn(baseInputClass, 'zd:w-full zd:pl-4 zd:pr-2', className)}
119
+ />
120
+ )
121
+ }
122
+
123
+ const heightClass = getHeightClass(multiline, variant)
124
+ const paddingLeft = variant === 'listItemStyle' ? 'zd:pl-2' : 'zd:pl-4'
125
+
126
+ return (
127
+ <Wrapper
128
+ data-testid="input-wrapper"
129
+ className={cn(
130
+ 'zd:relative zd:flex zd:w-full zd:rounded-2xl zd:items-center zd:gap-3 zd:pr-2',
131
+ heightClass,
132
+ paddingLeft,
133
+ containerClassName,
134
+ )}
135
+ variant="soft"
136
+ >
137
+ {/* On focus, overlay a white/20 tint over the soft (white/0.5) base so the
138
+ field matches the button hover state. */}
139
+ {isFocused && (
140
+ <div className="zd:absolute zd:inset-0 zd:bg-white/20 zd:pointer-events-none" />
141
+ )}
142
+ {iconName && <InputIcon variant={variant} iconName={iconName} />}
143
+ {inputElement}
144
+ {children}
145
+ </Wrapper>
146
+ )
147
+ }
@@ -0,0 +1,136 @@
1
+ import type { ButtonHTMLAttributes } from 'react'
2
+
3
+ import { cn } from '../../utils/common'
4
+ import { Badge, type BadgeProps } from '../Badge'
5
+ import { Icon, type IconName } from '../Icon'
6
+ import { Text } from '../Text'
7
+ import { Wrapper } from '../Wrapper'
8
+
9
+ interface ListItemSkeletonProps {
10
+ className?: string
11
+ }
12
+
13
+ export function ListItemSkeleton({ className }: ListItemSkeletonProps) {
14
+ return (
15
+ <div
16
+ className={cn(
17
+ 'zd:w-full zd:h-[68px] zd:rounded-2xl zd:border-offWhite zd:border-[0.3px]',
18
+ className,
19
+ )}
20
+ >
21
+ <div className="zd:flex zd:flex-row zd:justify-between zd:items-center zd:p-2">
22
+ <div className="zd:flex zd:flex-row zd:items-center zd:gap-3">
23
+ <div className="zd:w-[52px] zd:h-[52px] zd:rounded-2xl zd:bg-offWhite/50 zd:animate-pulse" />
24
+ <div className="zd:gap-2">
25
+ <div className="zd:w-14 zd:h-3 zd:rounded-lg zd:bg-offWhite/50 zd:animate-pulse zd:mb-2" />
26
+ <div className="zd:w-14 zd:h-3 zd:rounded-lg zd:bg-offWhite/50 zd:animate-pulse" />
27
+ </div>
28
+ </div>
29
+ <div className="zd:gap-2">
30
+ <div className="zd:w-14 zd:h-3 zd:rounded-lg zd:bg-offWhite/50 zd:animate-pulse zd:mb-2" />
31
+ <div className="zd:w-14 zd:h-3 zd:rounded-lg zd:bg-offWhite/50 zd:animate-pulse" />
32
+ </div>
33
+ </div>
34
+ </div>
35
+ )
36
+ }
37
+
38
+ export interface ListItemProps extends ButtonHTMLAttributes<HTMLButtonElement> {
39
+ iconName?: IconName
40
+ imageUri?: string
41
+ title: string
42
+ subtitle?: string
43
+ badgeProps?: BadgeProps
44
+ details?: { text: string; subtext?: string }
45
+ chevron?: boolean
46
+ alert?: boolean
47
+ }
48
+
49
+ export function ListItem({
50
+ iconName,
51
+ imageUri,
52
+ title,
53
+ subtitle,
54
+ badgeProps,
55
+ details,
56
+ chevron,
57
+ alert,
58
+ className,
59
+ ...rest
60
+ }: ListItemProps) {
61
+ return (
62
+ <Wrapper
63
+ className={cn(
64
+ 'zd:w-full zd:h-[68px] zd:rounded-2xl',
65
+ alert && 'zd:border-0',
66
+ className,
67
+ )}
68
+ >
69
+ <button
70
+ type="button"
71
+ className={cn(
72
+ 'zd:w-full zd:flex zd:flex-row zd:justify-between zd:items-center zd:p-2 zd:transition-colors zd:cursor-pointer',
73
+ alert
74
+ ? 'zd:bg-solarOrange/15'
75
+ : 'zd:hover:bg-white/20 zd:active:bg-white/30',
76
+ rest.disabled && 'zd:opacity-50 zd:cursor-not-allowed',
77
+ )}
78
+ {...rest}
79
+ >
80
+ <div className="zd:flex zd:flex-row zd:items-center zd:gap-3">
81
+ <div
82
+ className={cn(
83
+ 'zd:w-[52px] zd:h-[52px] zd:rounded-2xl zd:flex zd:items-center zd:justify-center zd:shrink-0',
84
+ alert ? 'zd:bg-offWhite/50' : 'zd:bg-white',
85
+ )}
86
+ >
87
+ {imageUri ? (
88
+ <img src={imageUri} alt="" className="zd:w-6 zd:h-6" />
89
+ ) : iconName ? (
90
+ <Icon
91
+ name={iconName}
92
+ className={cn(
93
+ 'zd:w-6 zd:h-6',
94
+ details || alert
95
+ ? 'zd:text-solarOrange'
96
+ : 'zd:text-greyScale',
97
+ )}
98
+ />
99
+ ) : null}
100
+ </div>
101
+ <div
102
+ className={cn(
103
+ 'zd:flex zd:flex-col zd:justify-center zd:text-left',
104
+ badgeProps ? 'zd:gap-2' : 'zd:gap-1',
105
+ )}
106
+ >
107
+ <Text className="zd:text-body1">{title}</Text>
108
+ {subtitle && (
109
+ <Text className="zd:text-body3 zd:text-greyScale/50">
110
+ {subtitle}
111
+ </Text>
112
+ )}
113
+ {badgeProps && <Badge {...badgeProps} />}
114
+ </div>
115
+ </div>
116
+ {details ? (
117
+ <div className="zd:flex zd:flex-col zd:pr-1">
118
+ <Text className="zd:text-body1">{details.text}</Text>
119
+ {details.subtext && (
120
+ <Text className="zd:text-body3 zd:text-greyScale/50 zd:self-end">
121
+ {details.subtext}
122
+ </Text>
123
+ )}
124
+ </div>
125
+ ) : chevron ? (
126
+ <div className="zd:w-13 zd:h-13 zd:flex zd:items-center zd:justify-center">
127
+ <Icon
128
+ name="chevronRight"
129
+ className="zd:h-6 zd:w-6 zd:text-greyScale"
130
+ />
131
+ </div>
132
+ ) : null}
133
+ </button>
134
+ </Wrapper>
135
+ )
136
+ }
@@ -0,0 +1,35 @@
1
+ import { cn } from '../../utils/common'
2
+ import { Text } from '../Text'
3
+ import { Wrapper } from '../Wrapper'
4
+
5
+ export interface SwitchProps {
6
+ value?: boolean
7
+ onValueChange?: () => void
8
+ }
9
+
10
+ export function Switch({ value, onValueChange }: SwitchProps) {
11
+ return (
12
+ <Wrapper variant="ghost" className="zd:w-14 zd:h-7 zd:rounded-xl zd:p-1">
13
+ <button
14
+ type="button"
15
+ role="switch"
16
+ aria-checked={value ?? false}
17
+ onClick={onValueChange}
18
+ className="zd:flex zd:items-center zd:justify-center zd:flex-row zd:gap-1.5 zd:w-full zd:h-full zd:rounded-lg zd:bg-white/70 zd:cursor-pointer"
19
+ >
20
+ {value && (
21
+ <Text className="zd:text-body3 zd:text-greyScale/90">On</Text>
22
+ )}
23
+ <div
24
+ className={cn(
25
+ 'zd:w-3.5 zd:h-3.5 zd:rounded-full zd:shadow-sm',
26
+ value ? 'zd:bg-solarOrange' : 'zd:bg-greyScale/30',
27
+ )}
28
+ />
29
+ {!value && (
30
+ <Text className="zd:text-body3 zd:text-greyScale/50">Off</Text>
31
+ )}
32
+ </button>
33
+ </Wrapper>
34
+ )
35
+ }
@@ -0,0 +1,20 @@
1
+ import type { AnchorHTMLAttributes, HTMLAttributes } from 'react'
2
+
3
+ import { cn } from '../../utils/common'
4
+
5
+ export type TextProps =
6
+ | ({ as?: 'p' | 'span' | 'label' } & HTMLAttributes<HTMLElement>)
7
+ | ({ as: 'a' } & AnchorHTMLAttributes<HTMLAnchorElement>)
8
+
9
+ export function Text({ as: Tag = 'p', className, ...props }: TextProps) {
10
+ return (
11
+ <Tag
12
+ className={cn(
13
+ 'zd:font-medium zd:font-sans zd:text-body2 zd:text-greyScale',
14
+ className,
15
+ )}
16
+ {...(props as HTMLAttributes<HTMLElement> &
17
+ AnchorHTMLAttributes<HTMLAnchorElement>)}
18
+ />
19
+ )
20
+ }