@mirohq/design-system-base-form 0.1.0-forms.0 → 0.1.0-forms.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.
package/dist/main.js CHANGED
@@ -5,6 +5,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
  var React = require('react');
7
7
  var designSystemUseId = require('@mirohq/design-system-use-id');
8
+ var designSystemUtils = require('@mirohq/design-system-utils');
8
9
  var designSystemStitches = require('@mirohq/design-system-stitches');
9
10
  var designSystemPrimitive = require('@mirohq/design-system-primitive');
10
11
  var designSystemBaseInput = require('@mirohq/design-system-base-input');
@@ -57,12 +58,11 @@ const FormFieldProvider = ({
57
58
  const message = document.getElementById(messageId);
58
59
  const helper = document.getElementById(helperId);
59
60
  const description = document.getElementById(descriptionId);
60
- const ariaDescribedBy2 = [
61
- // messge or description
62
- message != null ? messageId : description != null ? descriptionId : "",
63
- // helper
64
- helper != null ? helperId : ""
65
- ].join(" ").trim();
61
+ const ariaDescribedBy2 = designSystemUtils.stringAttrValue(
62
+ // message or description
63
+ message != null ? messageId : description != null && descriptionId,
64
+ helper != null && helperId
65
+ );
66
66
  setAriaDescribedBy(ariaDescribedBy2 === "" ? void 0 : ariaDescribedBy2);
67
67
  }, [messageId, helperId, descriptionId]);
68
68
  React.useEffect(() => {
@@ -130,25 +130,25 @@ const StyledFloatingLabel = designSystemStitches.styled(designSystemPrimitive.Pr
130
130
  position: "absolute",
131
131
  top: 0,
132
132
  left: 0,
133
+ zIndex: 1,
133
134
  pointerEvents: "none",
134
135
  whiteSpace: "nowrap",
136
+ fontStyle: "normal",
137
+ lineHeight: 1.5,
138
+ height: "0.75em",
135
139
  variants: {
136
140
  floating: {
137
141
  true: {
138
142
  top: "-$100",
139
143
  left: "$150",
140
144
  fontSize: "$150",
141
- lineHeight: 1.5,
142
- height: "1.5em",
143
145
  color: "$text-neutrals-subtle",
144
146
  padding: "0 2px",
145
147
  backgroundColor: "$background-neutrals-container"
146
148
  },
147
149
  false: {
148
150
  fontSize: "$200",
149
- lineHeight: 1.5,
150
- height: "1.5em",
151
- marginTop: "-2px",
151
+ marginTop: "-1px",
152
152
  // adjust for the input's border
153
153
  ...designSystemBaseInput.styles.base.placeholder
154
154
  }
@@ -156,16 +156,6 @@ const StyledFloatingLabel = designSystemStitches.styled(designSystemPrimitive.Pr
156
156
  size: {
157
157
  large: {},
158
158
  "x-large": {}
159
- },
160
- readOnly: {
161
- true: designSystemBaseInput.styles.variants.readOnly
162
- },
163
- disabled: {
164
- true: designSystemBaseInput.styles.base.disabled
165
- },
166
- ariaDisabled: {
167
- true: designSystemBaseInput.styles.base.disabled,
168
- false: {}
169
159
  }
170
160
  },
171
161
  compoundVariants: [
@@ -193,15 +183,12 @@ const StyledFloatingLabel = designSystemStitches.styled(designSystemPrimitive.Pr
193
183
  });
194
184
 
195
185
  const FloatingLabel = React__default["default"].forwardRef((props, forwardRef) => {
196
- const { isFloatingLabel, formElementId, disabled, ariaDisabled, readOnly } = useFormFieldContext();
186
+ const { isFloatingLabel, formElementId } = useFormFieldContext();
197
187
  return /* @__PURE__ */ jsxRuntime.jsx(
198
188
  StyledFloatingLabel,
199
189
  {
200
190
  htmlFor: formElementId,
201
191
  floating: isFloatingLabel,
202
- disabled,
203
- ariaDisabled,
204
- readOnly,
205
192
  ...props,
206
193
  ref: forwardRef
207
194
  }
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sources":["../src/constants.ts","../src/hooks/use-form-field-context.tsx","../src/floating-label.styled.ts","../src/floating-label.tsx"],"sourcesContent":["export const FORM_FIELD_STATUS = Object.freeze({\n // the field value is valid\n valid: 'valid',\n // the field value is invalid\n invalid: 'invalid',\n // the field value has been changed\n dirty: 'dirty',\n // the field value has not been changed\n pristine: 'pristine',\n // the field has been focused and blurred\n touched: 'touched',\n})\n\nexport type FormFieldStatus = keyof typeof FORM_FIELD_STATUS\n","import React, {\n createContext,\n useContext,\n useState,\n useRef,\n useEffect,\n} from 'react'\nimport type { PropsWithChildren, AriaAttributes } from 'react'\nimport type { Booleanish } from '@mirohq/design-system-types'\nimport { useId } from '@mirohq/design-system-use-id'\n\nimport type { FormFieldStatus } from '../constants'\nimport { FORM_FIELD_STATUS } from '../constants'\n\ninterface FormFieldProps {\n status?: FormFieldStatus\n id?: string\n}\n\ninterface FormFieldContextProps extends FormFieldProps {\n setStatus: React.Dispatch<React.SetStateAction<FormFieldStatus>>\n isFloatingLabel: boolean\n setIsFloatingLabel: React.Dispatch<React.SetStateAction<boolean>>\n label: React.ReactNode\n setLabel: React.Dispatch<React.SetStateAction<React.ReactNode>>\n focused: boolean\n setFocused: React.Dispatch<React.SetStateAction<boolean>>\n helperId: string\n setHelperId: React.Dispatch<React.SetStateAction<string>>\n messageId: string\n setMessageId: React.Dispatch<React.SetStateAction<string>>\n descriptionId: string\n setDescriptionId: React.Dispatch<React.SetStateAction<string>>\n formElementId: string\n formElementRef: React.RefObject<HTMLInputElement>\n ariaDescribedBy: string | undefined\n shouldUseFloatingLabel: boolean\n required: boolean | undefined\n setRequired: React.Dispatch<React.SetStateAction<boolean | undefined>>\n readOnly: boolean | undefined\n setReadOnly: React.Dispatch<React.SetStateAction<boolean | undefined>>\n disabled: boolean | undefined\n setDisabled: React.Dispatch<React.SetStateAction<boolean | undefined>>\n ariaDisabled: Booleanish | undefined\n setAriaDisabled: React.Dispatch<React.SetStateAction<Booleanish | undefined>>\n ariaInvalid: AriaAttributes['aria-invalid']\n setAriaInvalid: React.Dispatch<\n React.SetStateAction<AriaAttributes['aria-invalid']>\n >\n valid: boolean | undefined\n}\n\nexport type FormFieldProviderProps = Partial<FormFieldProps>\n\nconst FormFieldContext = createContext<FormFieldContextProps>({} as any)\n\nexport const FormFieldProvider = ({\n children,\n status: customStatus,\n id: customId,\n ...restProps\n}: PropsWithChildren<FormFieldProviderProps>): JSX.Element => {\n // form field state\n const [status, setStatus] = useState<FormFieldStatus>(\n customStatus ?? 'pristine'\n )\n const [focused, setFocused] = useState(false)\n const [isFloatingLabel, setIsFloatingLabel] = useState(true)\n const [label, setLabel] = useState<React.ReactNode>(null)\n const shouldUseFloatingLabel = label !== undefined && isFloatingLabel\n\n // partials\n const autoId = useId()\n const id = customId ?? autoId\n\n const [messageId, setMessageId] = useState(`${id}-message`)\n const [helperId, setHelperId] = useState(`${id}-helper`)\n const [descriptionId, setDescriptionId] = useState(`${id}-description`)\n\n // form element\n const formElementRef = useRef<HTMLInputElement>(null)\n const [required, setRequired] = useState<boolean>()\n const [readOnly, setReadOnly] = useState<boolean>()\n const [disabled, setDisabled] = useState<boolean>()\n const [ariaDisabled, setAriaDisabled] = useState<Booleanish>()\n const [ariaInvalid, setAriaInvalid] =\n useState<AriaAttributes['aria-invalid']>()\n const [ariaDescribedBy, setAriaDescribedBy] = useState<string | undefined>('')\n const [valid, setValid] = useState<boolean | undefined>(true)\n\n useEffect(() => {\n const message = document.getElementById(messageId)\n const helper = document.getElementById(helperId)\n const description = document.getElementById(descriptionId)\n const ariaDescribedBy = [\n // messge or description\n message != null ? messageId : description != null ? descriptionId : '',\n // helper\n helper != null ? helperId : '',\n ]\n .join(' ')\n .trim()\n\n /**\n * message + helper text\n * description + helper text\n */\n setAriaDescribedBy(ariaDescribedBy === '' ? undefined : ariaDescribedBy)\n }, [messageId, helperId, descriptionId])\n\n useEffect(() => {\n if (status === FORM_FIELD_STATUS.invalid) {\n setAriaInvalid(true)\n } else {\n setAriaInvalid(undefined)\n }\n }, [status])\n\n useEffect(() => {\n if (status === FORM_FIELD_STATUS.valid) {\n setValid(true)\n } else if (status === FORM_FIELD_STATUS.invalid) {\n setValid(false)\n } else {\n setValid(undefined)\n }\n }, [status])\n\n return (\n <FormFieldContext.Provider\n value={{\n ...restProps,\n id,\n formElementRef,\n formElementId: `${id}-form-element`,\n messageId,\n setMessageId,\n helperId,\n setHelperId,\n descriptionId,\n setDescriptionId,\n status,\n setStatus,\n focused,\n setFocused,\n isFloatingLabel,\n setIsFloatingLabel,\n label,\n setLabel,\n ariaDescribedBy,\n shouldUseFloatingLabel,\n required,\n setRequired,\n readOnly,\n setReadOnly,\n disabled,\n setDisabled,\n ariaDisabled,\n setAriaDisabled,\n ariaInvalid,\n setAriaInvalid,\n valid,\n }}\n >\n {children}\n </FormFieldContext.Provider>\n )\n}\n\nexport const useFormFieldContext = (): FormFieldContextProps =>\n useContext(FormFieldContext)\n","import type { ComponentPropsWithRef } from 'react'\nimport { styled } from '@mirohq/design-system-stitches'\nimport { Primitive } from '@mirohq/design-system-primitive'\nimport { styles as baseInputStyles } from '@mirohq/design-system-base-input'\n\nexport const StyledFloatingLabel = styled(Primitive.label, {\n transitionProperty: 'transform, margin, top, left, font-size',\n transitionDuration: '200ms',\n transitionTimingFunction: 'cubic-bezier(0, 0, 0.2, 1)',\n position: 'absolute',\n top: 0,\n left: 0,\n pointerEvents: 'none',\n whiteSpace: 'nowrap',\n variants: {\n floating: {\n true: {\n top: '-$100',\n left: '$150',\n\n fontSize: '$150',\n lineHeight: 1.5,\n height: '1.5em',\n\n color: '$text-neutrals-subtle',\n padding: '0 2px',\n backgroundColor: '$background-neutrals-container',\n },\n false: {\n fontSize: '$200',\n lineHeight: 1.5,\n height: '1.5em',\n marginTop: '-2px', // adjust for the input's border\n ...baseInputStyles.base.placeholder,\n },\n },\n size: {\n large: {},\n 'x-large': {},\n },\n readOnly: {\n true: baseInputStyles.variants.readOnly,\n },\n disabled: {\n true: baseInputStyles.base.disabled,\n },\n ariaDisabled: {\n true: baseInputStyles.base.disabled,\n false: {},\n },\n },\n compoundVariants: [\n {\n size: 'large',\n floating: false,\n css: {\n top: '$100',\n left: '$150',\n },\n },\n {\n size: 'x-large',\n floating: false,\n css: {\n top: '$150',\n // $space$250 does not exist by design but we will force it here\n left: 'calc($200 + $space$50)',\n },\n },\n ],\n defaultVariants: {\n size: 'large',\n },\n})\n\nexport type StyledFloatingLabelProps = ComponentPropsWithRef<\n typeof StyledFloatingLabel\n>\n","import React from 'react'\nimport type { ElementRef } from 'react'\n\nimport { useFormFieldContext } from './hooks/use-form-field-context'\nimport { StyledFloatingLabel } from './floating-label.styled'\nimport type { StyledFloatingLabelProps } from './floating-label.styled'\n\nexport interface FloatingLabelProps extends StyledFloatingLabelProps {}\n\nexport const FloatingLabel = React.forwardRef<\n ElementRef<typeof StyledFloatingLabel>,\n FloatingLabelProps\n>((props, forwardRef) => {\n const { isFloatingLabel, formElementId, disabled, ariaDisabled, readOnly } =\n useFormFieldContext()\n return (\n <StyledFloatingLabel\n htmlFor={formElementId}\n floating={isFloatingLabel}\n disabled={disabled}\n ariaDisabled={ariaDisabled}\n readOnly={readOnly}\n {...props}\n ref={forwardRef}\n />\n )\n})\n"],"names":["createContext","useState","useId","useRef","useEffect","ariaDescribedBy","jsx","useContext","styled","Primitive","baseInputStyles","React"],"mappings":";;;;;;;;;;;;;;;AAAa,MAAA,iBAAA,GAAoB,OAAO,MAAO,CAAA;AAAA;AAAA,EAE7C,KAAO,EAAA,OAAA;AAAA;AAAA,EAEP,OAAS,EAAA,SAAA;AAAA;AAAA,EAET,KAAO,EAAA,OAAA;AAAA;AAAA,EAEP,QAAU,EAAA,UAAA;AAAA;AAAA,EAEV,OAAS,EAAA,SAAA;AACX,CAAC;;AC2CD,MAAM,gBAAA,GAAmBA,mBAAqC,CAAA,EAAS,CAAA,CAAA;AAEhE,MAAM,oBAAoB,CAAC;AAAA,EAChC,QAAA;AAAA,EACA,MAAQ,EAAA,YAAA;AAAA,EACR,EAAI,EAAA,QAAA;AAAA,EACJ,GAAG,SAAA;AACL,CAA8D,KAAA;AAE5D,EAAM,MAAA,CAAC,MAAQ,EAAA,SAAS,CAAI,GAAAC,cAAA;AAAA,IAC1B,YAAgB,IAAA,IAAA,GAAA,YAAA,GAAA,UAAA;AAAA,GAClB,CAAA;AACA,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIA,eAAS,KAAK,CAAA,CAAA;AAC5C,EAAA,MAAM,CAAC,eAAA,EAAiB,kBAAkB,CAAA,GAAIA,eAAS,IAAI,CAAA,CAAA;AAC3D,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,eAA0B,IAAI,CAAA,CAAA;AACxD,EAAM,MAAA,sBAAA,GAAyB,UAAU,KAAa,CAAA,IAAA,eAAA,CAAA;AAGtD,EAAA,MAAM,SAASC,uBAAM,EAAA,CAAA;AACrB,EAAA,MAAM,KAAK,QAAY,IAAA,IAAA,GAAA,QAAA,GAAA,MAAA,CAAA;AAEvB,EAAA,MAAM,CAAC,SAAW,EAAA,YAAY,IAAID,cAAS,CAAA,EAAA,CAAG,WAAE,UAAU,CAAA,CAAA,CAAA;AAC1D,EAAA,MAAM,CAAC,QAAU,EAAA,WAAW,IAAIA,cAAS,CAAA,EAAA,CAAG,WAAE,SAAS,CAAA,CAAA,CAAA;AACvD,EAAA,MAAM,CAAC,aAAe,EAAA,gBAAgB,IAAIA,cAAS,CAAA,EAAA,CAAG,WAAE,cAAc,CAAA,CAAA,CAAA;AAGtE,EAAM,MAAA,cAAA,GAAiBE,aAAyB,IAAI,CAAA,CAAA;AACpD,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIF,cAAkB,EAAA,CAAA;AAClD,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIA,cAAkB,EAAA,CAAA;AAClD,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIA,cAAkB,EAAA,CAAA;AAClD,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAIA,cAAqB,EAAA,CAAA;AAC7D,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAChCA,cAAyC,EAAA,CAAA;AAC3C,EAAA,MAAM,CAAC,eAAA,EAAiB,kBAAkB,CAAA,GAAIA,eAA6B,EAAE,CAAA,CAAA;AAC7E,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,eAA8B,IAAI,CAAA,CAAA;AAE5D,EAAAG,eAAA,CAAU,MAAM;AACd,IAAM,MAAA,OAAA,GAAU,QAAS,CAAA,cAAA,CAAe,SAAS,CAAA,CAAA;AACjD,IAAM,MAAA,MAAA,GAAS,QAAS,CAAA,cAAA,CAAe,QAAQ,CAAA,CAAA;AAC/C,IAAM,MAAA,WAAA,GAAc,QAAS,CAAA,cAAA,CAAe,aAAa,CAAA,CAAA;AACzD,IAAA,MAAMC,gBAAkB,GAAA;AAAA;AAAA,MAEtB,OAAW,IAAA,IAAA,GAAO,SAAY,GAAA,WAAA,IAAe,OAAO,aAAgB,GAAA,EAAA;AAAA;AAAA,MAEpE,MAAA,IAAU,OAAO,QAAW,GAAA,EAAA;AAAA,KAE3B,CAAA,IAAA,CAAK,GAAG,CAAA,CACR,IAAK,EAAA,CAAA;AAMR,IAAmBA,kBAAAA,CAAAA,gBAAAA,KAAoB,EAAK,GAAA,KAAA,CAAA,GAAYA,gBAAe,CAAA,CAAA;AAAA,GACtE,EAAA,CAAC,SAAW,EAAA,QAAA,EAAU,aAAa,CAAC,CAAA,CAAA;AAEvC,EAAAD,eAAA,CAAU,MAAM;AACd,IAAI,IAAA,MAAA,KAAW,kBAAkB,OAAS,EAAA;AACxC,MAAA,cAAA,CAAe,IAAI,CAAA,CAAA;AAAA,KACd,MAAA;AACL,MAAA,cAAA,CAAe,KAAS,CAAA,CAAA,CAAA;AAAA,KAC1B;AAAA,GACF,EAAG,CAAC,MAAM,CAAC,CAAA,CAAA;AAEX,EAAAA,eAAA,CAAU,MAAM;AACd,IAAI,IAAA,MAAA,KAAW,kBAAkB,KAAO,EAAA;AACtC,MAAA,QAAA,CAAS,IAAI,CAAA,CAAA;AAAA,KACf,MAAA,IAAW,MAAW,KAAA,iBAAA,CAAkB,OAAS,EAAA;AAC/C,MAAA,QAAA,CAAS,KAAK,CAAA,CAAA;AAAA,KACT,MAAA;AACL,MAAA,QAAA,CAAS,KAAS,CAAA,CAAA,CAAA;AAAA,KACpB;AAAA,GACF,EAAG,CAAC,MAAM,CAAC,CAAA,CAAA;AAEX,EACE,uBAAAE,cAAA;AAAA,IAAC,gBAAiB,CAAA,QAAA;AAAA,IAAjB;AAAA,MACC,KAAO,EAAA;AAAA,QACL,GAAG,SAAA;AAAA,QACH,EAAA;AAAA,QACA,cAAA;AAAA,QACA,aAAA,EAAe,GAAG,MAAE,CAAA,EAAA,EAAA,eAAA,CAAA;AAAA,QACpB,SAAA;AAAA,QACA,YAAA;AAAA,QACA,QAAA;AAAA,QACA,WAAA;AAAA,QACA,aAAA;AAAA,QACA,gBAAA;AAAA,QACA,MAAA;AAAA,QACA,SAAA;AAAA,QACA,OAAA;AAAA,QACA,UAAA;AAAA,QACA,eAAA;AAAA,QACA,kBAAA;AAAA,QACA,KAAA;AAAA,QACA,QAAA;AAAA,QACA,eAAA;AAAA,QACA,sBAAA;AAAA,QACA,QAAA;AAAA,QACA,WAAA;AAAA,QACA,QAAA;AAAA,QACA,WAAA;AAAA,QACA,QAAA;AAAA,QACA,WAAA;AAAA,QACA,YAAA;AAAA,QACA,eAAA;AAAA,QACA,WAAA;AAAA,QACA,cAAA;AAAA,QACA,KAAA;AAAA,OACF;AAAA,MAEC,QAAA;AAAA,KAAA;AAAA,GACH,CAAA;AAEJ,EAAA;AAEa,MAAA,mBAAA,GAAsB,MACjCC,gBAAA,CAAW,gBAAgB;;ACrKhB,MAAA,mBAAA,GAAsBC,2BAAO,CAAAC,+BAAA,CAAU,KAAO,EAAA;AAAA,EACzD,kBAAoB,EAAA,yCAAA;AAAA,EACpB,kBAAoB,EAAA,OAAA;AAAA,EACpB,wBAA0B,EAAA,4BAAA;AAAA,EAC1B,QAAU,EAAA,UAAA;AAAA,EACV,GAAK,EAAA,CAAA;AAAA,EACL,IAAM,EAAA,CAAA;AAAA,EACN,aAAe,EAAA,MAAA;AAAA,EACf,UAAY,EAAA,QAAA;AAAA,EACZ,QAAU,EAAA;AAAA,IACR,QAAU,EAAA;AAAA,MACR,IAAM,EAAA;AAAA,QACJ,GAAK,EAAA,OAAA;AAAA,QACL,IAAM,EAAA,MAAA;AAAA,QAEN,QAAU,EAAA,MAAA;AAAA,QACV,UAAY,EAAA,GAAA;AAAA,QACZ,MAAQ,EAAA,OAAA;AAAA,QAER,KAAO,EAAA,uBAAA;AAAA,QACP,OAAS,EAAA,OAAA;AAAA,QACT,eAAiB,EAAA,gCAAA;AAAA,OACnB;AAAA,MACA,KAAO,EAAA;AAAA,QACL,QAAU,EAAA,MAAA;AAAA,QACV,UAAY,EAAA,GAAA;AAAA,QACZ,MAAQ,EAAA,OAAA;AAAA,QACR,SAAW,EAAA,MAAA;AAAA;AAAA,QACX,GAAGC,6BAAgB,IAAK,CAAA,WAAA;AAAA,OAC1B;AAAA,KACF;AAAA,IACA,IAAM,EAAA;AAAA,MACJ,OAAO,EAAC;AAAA,MACR,WAAW,EAAC;AAAA,KACd;AAAA,IACA,QAAU,EAAA;AAAA,MACR,IAAA,EAAMA,6BAAgB,QAAS,CAAA,QAAA;AAAA,KACjC;AAAA,IACA,QAAU,EAAA;AAAA,MACR,IAAA,EAAMA,6BAAgB,IAAK,CAAA,QAAA;AAAA,KAC7B;AAAA,IACA,YAAc,EAAA;AAAA,MACZ,IAAA,EAAMA,6BAAgB,IAAK,CAAA,QAAA;AAAA,MAC3B,OAAO,EAAC;AAAA,KACV;AAAA,GACF;AAAA,EACA,gBAAkB,EAAA;AAAA,IAChB;AAAA,MACE,IAAM,EAAA,OAAA;AAAA,MACN,QAAU,EAAA,KAAA;AAAA,MACV,GAAK,EAAA;AAAA,QACH,GAAK,EAAA,MAAA;AAAA,QACL,IAAM,EAAA,MAAA;AAAA,OACR;AAAA,KACF;AAAA,IACA;AAAA,MACE,IAAM,EAAA,SAAA;AAAA,MACN,QAAU,EAAA,KAAA;AAAA,MACV,GAAK,EAAA;AAAA,QACH,GAAK,EAAA,MAAA;AAAA;AAAA,QAEL,IAAM,EAAA,wBAAA;AAAA,OACR;AAAA,KACF;AAAA,GACF;AAAA,EACA,eAAiB,EAAA;AAAA,IACf,IAAM,EAAA,OAAA;AAAA,GACR;AACF,CAAC,CAAA;;AChEM,MAAM,aAAgB,GAAAC,yBAAA,CAAM,UAGjC,CAAA,CAAC,OAAO,UAAe,KAAA;AACvB,EAAA,MAAM,EAAE,eAAiB,EAAA,aAAA,EAAe,UAAU,YAAc,EAAA,QAAA,KAC9D,mBAAoB,EAAA,CAAA;AACtB,EACE,uBAAAL,cAAA;AAAA,IAAC,mBAAA;AAAA,IAAA;AAAA,MACC,OAAS,EAAA,aAAA;AAAA,MACT,QAAU,EAAA,eAAA;AAAA,MACV,QAAA;AAAA,MACA,YAAA;AAAA,MACA,QAAA;AAAA,MACC,GAAG,KAAA;AAAA,MACJ,GAAK,EAAA,UAAA;AAAA,KAAA;AAAA,GACP,CAAA;AAEJ,CAAC;;;;;;;"}
1
+ {"version":3,"file":"main.js","sources":["../src/constants.ts","../src/hooks/use-form-field-context.tsx","../src/floating-label.styled.ts","../src/floating-label.tsx"],"sourcesContent":["export const FORM_FIELD_STATUS = Object.freeze({\n // the field value is valid\n valid: 'valid',\n // the field value is invalid\n invalid: 'invalid',\n // the field value has been changed\n dirty: 'dirty',\n // the field value has not been changed\n pristine: 'pristine',\n // the field has been focused and blurred\n touched: 'touched',\n})\n\nexport type FormFieldStatus = keyof typeof FORM_FIELD_STATUS\n","import React, {\n createContext,\n useContext,\n useState,\n useRef,\n useEffect,\n} from 'react'\nimport type { PropsWithChildren, AriaAttributes } from 'react'\nimport type { Booleanish } from '@mirohq/design-system-types'\nimport { useId } from '@mirohq/design-system-use-id'\nimport { stringAttrValue } from '@mirohq/design-system-utils'\n\nimport type { FormFieldStatus } from '../constants'\nimport { FORM_FIELD_STATUS } from '../constants'\n\ntype FormElements = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement\n\ninterface FormFieldProps {\n /**\n * Field status\n * @default \"pristine\"\n */\n status?: FormFieldStatus\n\n id?: string\n}\n\ninterface FormFieldContextProps<FormElementRef extends FormElements>\n extends FormFieldProps {\n setStatus: React.Dispatch<React.SetStateAction<FormFieldStatus>>\n isFloatingLabel: boolean\n setIsFloatingLabel: React.Dispatch<React.SetStateAction<boolean>>\n label: React.ReactNode\n setLabel: React.Dispatch<React.SetStateAction<React.ReactNode>>\n focused: boolean\n setFocused: React.Dispatch<React.SetStateAction<boolean>>\n helperId: string\n setHelperId: React.Dispatch<React.SetStateAction<string>>\n messageId: string\n setMessageId: React.Dispatch<React.SetStateAction<string>>\n descriptionId: string\n setDescriptionId: React.Dispatch<React.SetStateAction<string>>\n formElementId: string\n formElementRef: React.MutableRefObject<FormElementRef>\n ariaDescribedBy: string | undefined\n shouldUseFloatingLabel: boolean\n required: boolean | undefined\n setRequired: React.Dispatch<React.SetStateAction<boolean | undefined>>\n readOnly: boolean | undefined\n setReadOnly: React.Dispatch<React.SetStateAction<boolean | undefined>>\n disabled: boolean | undefined\n setDisabled: React.Dispatch<React.SetStateAction<boolean | undefined>>\n ariaDisabled: Booleanish | undefined\n setAriaDisabled: React.Dispatch<React.SetStateAction<Booleanish | undefined>>\n ariaInvalid: AriaAttributes['aria-invalid']\n setAriaInvalid: React.Dispatch<\n React.SetStateAction<AriaAttributes['aria-invalid']>\n >\n valid: boolean | undefined\n}\n\nexport type FormFieldProviderProps = Partial<FormFieldProps>\n\nconst FormFieldContext = createContext<FormFieldContextProps<any>>({} as any)\n\nexport const FormFieldProvider = ({\n children,\n status: customStatus,\n id: customId,\n ...restProps\n}: PropsWithChildren<FormFieldProviderProps>): JSX.Element => {\n // form field state\n const [status, setStatus] = useState<FormFieldStatus>(\n customStatus ?? 'pristine'\n )\n const [focused, setFocused] = useState(false)\n const [isFloatingLabel, setIsFloatingLabel] = useState(true)\n const [label, setLabel] = useState<React.ReactNode>(null)\n const shouldUseFloatingLabel = label !== undefined && isFloatingLabel\n\n // partials\n const autoId = useId()\n const id = customId ?? autoId\n\n const [messageId, setMessageId] = useState(`${id}-message`)\n const [helperId, setHelperId] = useState(`${id}-helper`)\n const [descriptionId, setDescriptionId] = useState(`${id}-description`)\n\n // form element\n const formElementRef = useRef<HTMLInputElement>(null)\n const [required, setRequired] = useState<boolean>()\n const [readOnly, setReadOnly] = useState<boolean>()\n const [disabled, setDisabled] = useState<boolean>()\n const [ariaDisabled, setAriaDisabled] = useState<Booleanish>()\n const [ariaInvalid, setAriaInvalid] =\n useState<AriaAttributes['aria-invalid']>()\n const [ariaDescribedBy, setAriaDescribedBy] = useState<string | undefined>('')\n const [valid, setValid] = useState<boolean | undefined>(true)\n\n useEffect(() => {\n const message = document.getElementById(messageId)\n const helper = document.getElementById(helperId)\n const description = document.getElementById(descriptionId)\n\n const ariaDescribedBy = stringAttrValue(\n // message or description\n message != null ? messageId : description != null && descriptionId,\n helper != null && helperId\n )\n\n /**\n * message + helper text\n * description + helper text\n */\n setAriaDescribedBy(ariaDescribedBy === '' ? undefined : ariaDescribedBy)\n }, [messageId, helperId, descriptionId])\n\n useEffect(() => {\n if (status === FORM_FIELD_STATUS.invalid) {\n setAriaInvalid(true)\n } else {\n setAriaInvalid(undefined)\n }\n }, [status])\n\n useEffect(() => {\n if (status === FORM_FIELD_STATUS.valid) {\n setValid(true)\n } else if (status === FORM_FIELD_STATUS.invalid) {\n setValid(false)\n } else {\n setValid(undefined)\n }\n }, [status])\n\n return (\n <FormFieldContext.Provider\n value={{\n ...restProps,\n id,\n formElementRef,\n formElementId: `${id}-form-element`,\n messageId,\n setMessageId,\n helperId,\n setHelperId,\n descriptionId,\n setDescriptionId,\n status,\n setStatus,\n focused,\n setFocused,\n isFloatingLabel,\n setIsFloatingLabel,\n label,\n setLabel,\n ariaDescribedBy,\n shouldUseFloatingLabel,\n required,\n setRequired,\n readOnly,\n setReadOnly,\n disabled,\n setDisabled,\n ariaDisabled,\n setAriaDisabled,\n ariaInvalid,\n setAriaInvalid,\n valid,\n }}\n >\n {children}\n </FormFieldContext.Provider>\n )\n}\n\nexport const useFormFieldContext = <\n T extends FormElements\n>(): FormFieldContextProps<T> => useContext(FormFieldContext)\n","import type { ComponentPropsWithRef } from 'react'\nimport { styled } from '@mirohq/design-system-stitches'\nimport { Primitive } from '@mirohq/design-system-primitive'\nimport { styles as baseInputStyles } from '@mirohq/design-system-base-input'\n\nexport const StyledFloatingLabel = styled(Primitive.label, {\n transitionProperty: 'transform, margin, top, left, font-size',\n transitionDuration: '200ms',\n transitionTimingFunction: 'cubic-bezier(0, 0, 0.2, 1)',\n position: 'absolute',\n top: 0,\n left: 0,\n zIndex: 1,\n pointerEvents: 'none',\n whiteSpace: 'nowrap',\n fontStyle: 'normal',\n lineHeight: 1.5,\n height: '0.75em',\n variants: {\n floating: {\n true: {\n top: '-$100',\n left: '$150',\n fontSize: '$150',\n color: '$text-neutrals-subtle',\n padding: '0 2px',\n backgroundColor: '$background-neutrals-container',\n },\n false: {\n fontSize: '$200',\n marginTop: '-1px', // adjust for the input's border\n ...baseInputStyles.base.placeholder,\n },\n },\n size: {\n large: {},\n 'x-large': {},\n },\n },\n compoundVariants: [\n {\n size: 'large',\n floating: false,\n css: {\n top: '$100',\n left: '$150',\n },\n },\n {\n size: 'x-large',\n floating: false,\n css: {\n top: '$150',\n // $space$250 does not exist by design but we will force it here\n left: 'calc($200 + $space$50)',\n },\n },\n ],\n defaultVariants: {\n size: 'large',\n },\n})\n\nexport type StyledFloatingLabelProps = ComponentPropsWithRef<\n typeof StyledFloatingLabel\n>\n","import React from 'react'\nimport type { ElementRef } from 'react'\n\nimport { useFormFieldContext } from './hooks/use-form-field-context'\nimport { StyledFloatingLabel } from './floating-label.styled'\nimport type { StyledFloatingLabelProps } from './floating-label.styled'\n\nexport interface FloatingLabelProps extends StyledFloatingLabelProps {}\n\nexport const FloatingLabel = React.forwardRef<\n ElementRef<typeof StyledFloatingLabel>,\n FloatingLabelProps\n>((props, forwardRef) => {\n const { isFloatingLabel, formElementId } = useFormFieldContext()\n\n return (\n <StyledFloatingLabel\n htmlFor={formElementId}\n floating={isFloatingLabel}\n {...props}\n ref={forwardRef}\n />\n )\n})\n"],"names":["createContext","useState","useId","useRef","useEffect","ariaDescribedBy","stringAttrValue","jsx","useContext","styled","Primitive","baseInputStyles","React"],"mappings":"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"}
package/dist/module.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import React, { createContext, useState, useRef, useEffect, useContext } from 'react';
3
3
  import { useId } from '@mirohq/design-system-use-id';
4
+ import { stringAttrValue } from '@mirohq/design-system-utils';
4
5
  import { styled } from '@mirohq/design-system-stitches';
5
6
  import { Primitive } from '@mirohq/design-system-primitive';
6
7
  import { styles } from '@mirohq/design-system-base-input';
@@ -49,12 +50,11 @@ const FormFieldProvider = ({
49
50
  const message = document.getElementById(messageId);
50
51
  const helper = document.getElementById(helperId);
51
52
  const description = document.getElementById(descriptionId);
52
- const ariaDescribedBy2 = [
53
- // messge or description
54
- message != null ? messageId : description != null ? descriptionId : "",
55
- // helper
56
- helper != null ? helperId : ""
57
- ].join(" ").trim();
53
+ const ariaDescribedBy2 = stringAttrValue(
54
+ // message or description
55
+ message != null ? messageId : description != null && descriptionId,
56
+ helper != null && helperId
57
+ );
58
58
  setAriaDescribedBy(ariaDescribedBy2 === "" ? void 0 : ariaDescribedBy2);
59
59
  }, [messageId, helperId, descriptionId]);
60
60
  useEffect(() => {
@@ -122,25 +122,25 @@ const StyledFloatingLabel = styled(Primitive.label, {
122
122
  position: "absolute",
123
123
  top: 0,
124
124
  left: 0,
125
+ zIndex: 1,
125
126
  pointerEvents: "none",
126
127
  whiteSpace: "nowrap",
128
+ fontStyle: "normal",
129
+ lineHeight: 1.5,
130
+ height: "0.75em",
127
131
  variants: {
128
132
  floating: {
129
133
  true: {
130
134
  top: "-$100",
131
135
  left: "$150",
132
136
  fontSize: "$150",
133
- lineHeight: 1.5,
134
- height: "1.5em",
135
137
  color: "$text-neutrals-subtle",
136
138
  padding: "0 2px",
137
139
  backgroundColor: "$background-neutrals-container"
138
140
  },
139
141
  false: {
140
142
  fontSize: "$200",
141
- lineHeight: 1.5,
142
- height: "1.5em",
143
- marginTop: "-2px",
143
+ marginTop: "-1px",
144
144
  // adjust for the input's border
145
145
  ...styles.base.placeholder
146
146
  }
@@ -148,16 +148,6 @@ const StyledFloatingLabel = styled(Primitive.label, {
148
148
  size: {
149
149
  large: {},
150
150
  "x-large": {}
151
- },
152
- readOnly: {
153
- true: styles.variants.readOnly
154
- },
155
- disabled: {
156
- true: styles.base.disabled
157
- },
158
- ariaDisabled: {
159
- true: styles.base.disabled,
160
- false: {}
161
151
  }
162
152
  },
163
153
  compoundVariants: [
@@ -185,15 +175,12 @@ const StyledFloatingLabel = styled(Primitive.label, {
185
175
  });
186
176
 
187
177
  const FloatingLabel = React.forwardRef((props, forwardRef) => {
188
- const { isFloatingLabel, formElementId, disabled, ariaDisabled, readOnly } = useFormFieldContext();
178
+ const { isFloatingLabel, formElementId } = useFormFieldContext();
189
179
  return /* @__PURE__ */ jsx(
190
180
  StyledFloatingLabel,
191
181
  {
192
182
  htmlFor: formElementId,
193
183
  floating: isFloatingLabel,
194
- disabled,
195
- ariaDisabled,
196
- readOnly,
197
184
  ...props,
198
185
  ref: forwardRef
199
186
  }
@@ -1 +1 @@
1
- {"version":3,"file":"module.js","sources":["../src/constants.ts","../src/hooks/use-form-field-context.tsx","../src/floating-label.styled.ts","../src/floating-label.tsx"],"sourcesContent":["export const FORM_FIELD_STATUS = Object.freeze({\n // the field value is valid\n valid: 'valid',\n // the field value is invalid\n invalid: 'invalid',\n // the field value has been changed\n dirty: 'dirty',\n // the field value has not been changed\n pristine: 'pristine',\n // the field has been focused and blurred\n touched: 'touched',\n})\n\nexport type FormFieldStatus = keyof typeof FORM_FIELD_STATUS\n","import React, {\n createContext,\n useContext,\n useState,\n useRef,\n useEffect,\n} from 'react'\nimport type { PropsWithChildren, AriaAttributes } from 'react'\nimport type { Booleanish } from '@mirohq/design-system-types'\nimport { useId } from '@mirohq/design-system-use-id'\n\nimport type { FormFieldStatus } from '../constants'\nimport { FORM_FIELD_STATUS } from '../constants'\n\ninterface FormFieldProps {\n status?: FormFieldStatus\n id?: string\n}\n\ninterface FormFieldContextProps extends FormFieldProps {\n setStatus: React.Dispatch<React.SetStateAction<FormFieldStatus>>\n isFloatingLabel: boolean\n setIsFloatingLabel: React.Dispatch<React.SetStateAction<boolean>>\n label: React.ReactNode\n setLabel: React.Dispatch<React.SetStateAction<React.ReactNode>>\n focused: boolean\n setFocused: React.Dispatch<React.SetStateAction<boolean>>\n helperId: string\n setHelperId: React.Dispatch<React.SetStateAction<string>>\n messageId: string\n setMessageId: React.Dispatch<React.SetStateAction<string>>\n descriptionId: string\n setDescriptionId: React.Dispatch<React.SetStateAction<string>>\n formElementId: string\n formElementRef: React.RefObject<HTMLInputElement>\n ariaDescribedBy: string | undefined\n shouldUseFloatingLabel: boolean\n required: boolean | undefined\n setRequired: React.Dispatch<React.SetStateAction<boolean | undefined>>\n readOnly: boolean | undefined\n setReadOnly: React.Dispatch<React.SetStateAction<boolean | undefined>>\n disabled: boolean | undefined\n setDisabled: React.Dispatch<React.SetStateAction<boolean | undefined>>\n ariaDisabled: Booleanish | undefined\n setAriaDisabled: React.Dispatch<React.SetStateAction<Booleanish | undefined>>\n ariaInvalid: AriaAttributes['aria-invalid']\n setAriaInvalid: React.Dispatch<\n React.SetStateAction<AriaAttributes['aria-invalid']>\n >\n valid: boolean | undefined\n}\n\nexport type FormFieldProviderProps = Partial<FormFieldProps>\n\nconst FormFieldContext = createContext<FormFieldContextProps>({} as any)\n\nexport const FormFieldProvider = ({\n children,\n status: customStatus,\n id: customId,\n ...restProps\n}: PropsWithChildren<FormFieldProviderProps>): JSX.Element => {\n // form field state\n const [status, setStatus] = useState<FormFieldStatus>(\n customStatus ?? 'pristine'\n )\n const [focused, setFocused] = useState(false)\n const [isFloatingLabel, setIsFloatingLabel] = useState(true)\n const [label, setLabel] = useState<React.ReactNode>(null)\n const shouldUseFloatingLabel = label !== undefined && isFloatingLabel\n\n // partials\n const autoId = useId()\n const id = customId ?? autoId\n\n const [messageId, setMessageId] = useState(`${id}-message`)\n const [helperId, setHelperId] = useState(`${id}-helper`)\n const [descriptionId, setDescriptionId] = useState(`${id}-description`)\n\n // form element\n const formElementRef = useRef<HTMLInputElement>(null)\n const [required, setRequired] = useState<boolean>()\n const [readOnly, setReadOnly] = useState<boolean>()\n const [disabled, setDisabled] = useState<boolean>()\n const [ariaDisabled, setAriaDisabled] = useState<Booleanish>()\n const [ariaInvalid, setAriaInvalid] =\n useState<AriaAttributes['aria-invalid']>()\n const [ariaDescribedBy, setAriaDescribedBy] = useState<string | undefined>('')\n const [valid, setValid] = useState<boolean | undefined>(true)\n\n useEffect(() => {\n const message = document.getElementById(messageId)\n const helper = document.getElementById(helperId)\n const description = document.getElementById(descriptionId)\n const ariaDescribedBy = [\n // messge or description\n message != null ? messageId : description != null ? descriptionId : '',\n // helper\n helper != null ? helperId : '',\n ]\n .join(' ')\n .trim()\n\n /**\n * message + helper text\n * description + helper text\n */\n setAriaDescribedBy(ariaDescribedBy === '' ? undefined : ariaDescribedBy)\n }, [messageId, helperId, descriptionId])\n\n useEffect(() => {\n if (status === FORM_FIELD_STATUS.invalid) {\n setAriaInvalid(true)\n } else {\n setAriaInvalid(undefined)\n }\n }, [status])\n\n useEffect(() => {\n if (status === FORM_FIELD_STATUS.valid) {\n setValid(true)\n } else if (status === FORM_FIELD_STATUS.invalid) {\n setValid(false)\n } else {\n setValid(undefined)\n }\n }, [status])\n\n return (\n <FormFieldContext.Provider\n value={{\n ...restProps,\n id,\n formElementRef,\n formElementId: `${id}-form-element`,\n messageId,\n setMessageId,\n helperId,\n setHelperId,\n descriptionId,\n setDescriptionId,\n status,\n setStatus,\n focused,\n setFocused,\n isFloatingLabel,\n setIsFloatingLabel,\n label,\n setLabel,\n ariaDescribedBy,\n shouldUseFloatingLabel,\n required,\n setRequired,\n readOnly,\n setReadOnly,\n disabled,\n setDisabled,\n ariaDisabled,\n setAriaDisabled,\n ariaInvalid,\n setAriaInvalid,\n valid,\n }}\n >\n {children}\n </FormFieldContext.Provider>\n )\n}\n\nexport const useFormFieldContext = (): FormFieldContextProps =>\n useContext(FormFieldContext)\n","import type { ComponentPropsWithRef } from 'react'\nimport { styled } from '@mirohq/design-system-stitches'\nimport { Primitive } from '@mirohq/design-system-primitive'\nimport { styles as baseInputStyles } from '@mirohq/design-system-base-input'\n\nexport const StyledFloatingLabel = styled(Primitive.label, {\n transitionProperty: 'transform, margin, top, left, font-size',\n transitionDuration: '200ms',\n transitionTimingFunction: 'cubic-bezier(0, 0, 0.2, 1)',\n position: 'absolute',\n top: 0,\n left: 0,\n pointerEvents: 'none',\n whiteSpace: 'nowrap',\n variants: {\n floating: {\n true: {\n top: '-$100',\n left: '$150',\n\n fontSize: '$150',\n lineHeight: 1.5,\n height: '1.5em',\n\n color: '$text-neutrals-subtle',\n padding: '0 2px',\n backgroundColor: '$background-neutrals-container',\n },\n false: {\n fontSize: '$200',\n lineHeight: 1.5,\n height: '1.5em',\n marginTop: '-2px', // adjust for the input's border\n ...baseInputStyles.base.placeholder,\n },\n },\n size: {\n large: {},\n 'x-large': {},\n },\n readOnly: {\n true: baseInputStyles.variants.readOnly,\n },\n disabled: {\n true: baseInputStyles.base.disabled,\n },\n ariaDisabled: {\n true: baseInputStyles.base.disabled,\n false: {},\n },\n },\n compoundVariants: [\n {\n size: 'large',\n floating: false,\n css: {\n top: '$100',\n left: '$150',\n },\n },\n {\n size: 'x-large',\n floating: false,\n css: {\n top: '$150',\n // $space$250 does not exist by design but we will force it here\n left: 'calc($200 + $space$50)',\n },\n },\n ],\n defaultVariants: {\n size: 'large',\n },\n})\n\nexport type StyledFloatingLabelProps = ComponentPropsWithRef<\n typeof StyledFloatingLabel\n>\n","import React from 'react'\nimport type { ElementRef } from 'react'\n\nimport { useFormFieldContext } from './hooks/use-form-field-context'\nimport { StyledFloatingLabel } from './floating-label.styled'\nimport type { StyledFloatingLabelProps } from './floating-label.styled'\n\nexport interface FloatingLabelProps extends StyledFloatingLabelProps {}\n\nexport const FloatingLabel = React.forwardRef<\n ElementRef<typeof StyledFloatingLabel>,\n FloatingLabelProps\n>((props, forwardRef) => {\n const { isFloatingLabel, formElementId, disabled, ariaDisabled, readOnly } =\n useFormFieldContext()\n return (\n <StyledFloatingLabel\n htmlFor={formElementId}\n floating={isFloatingLabel}\n disabled={disabled}\n ariaDisabled={ariaDisabled}\n readOnly={readOnly}\n {...props}\n ref={forwardRef}\n />\n )\n})\n"],"names":["ariaDescribedBy","baseInputStyles"],"mappings":"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"}
1
+ {"version":3,"file":"module.js","sources":["../src/constants.ts","../src/hooks/use-form-field-context.tsx","../src/floating-label.styled.ts","../src/floating-label.tsx"],"sourcesContent":["export const FORM_FIELD_STATUS = Object.freeze({\n // the field value is valid\n valid: 'valid',\n // the field value is invalid\n invalid: 'invalid',\n // the field value has been changed\n dirty: 'dirty',\n // the field value has not been changed\n pristine: 'pristine',\n // the field has been focused and blurred\n touched: 'touched',\n})\n\nexport type FormFieldStatus = keyof typeof FORM_FIELD_STATUS\n","import React, {\n createContext,\n useContext,\n useState,\n useRef,\n useEffect,\n} from 'react'\nimport type { PropsWithChildren, AriaAttributes } from 'react'\nimport type { Booleanish } from '@mirohq/design-system-types'\nimport { useId } from '@mirohq/design-system-use-id'\nimport { stringAttrValue } from '@mirohq/design-system-utils'\n\nimport type { FormFieldStatus } from '../constants'\nimport { FORM_FIELD_STATUS } from '../constants'\n\ntype FormElements = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement\n\ninterface FormFieldProps {\n /**\n * Field status\n * @default \"pristine\"\n */\n status?: FormFieldStatus\n\n id?: string\n}\n\ninterface FormFieldContextProps<FormElementRef extends FormElements>\n extends FormFieldProps {\n setStatus: React.Dispatch<React.SetStateAction<FormFieldStatus>>\n isFloatingLabel: boolean\n setIsFloatingLabel: React.Dispatch<React.SetStateAction<boolean>>\n label: React.ReactNode\n setLabel: React.Dispatch<React.SetStateAction<React.ReactNode>>\n focused: boolean\n setFocused: React.Dispatch<React.SetStateAction<boolean>>\n helperId: string\n setHelperId: React.Dispatch<React.SetStateAction<string>>\n messageId: string\n setMessageId: React.Dispatch<React.SetStateAction<string>>\n descriptionId: string\n setDescriptionId: React.Dispatch<React.SetStateAction<string>>\n formElementId: string\n formElementRef: React.MutableRefObject<FormElementRef>\n ariaDescribedBy: string | undefined\n shouldUseFloatingLabel: boolean\n required: boolean | undefined\n setRequired: React.Dispatch<React.SetStateAction<boolean | undefined>>\n readOnly: boolean | undefined\n setReadOnly: React.Dispatch<React.SetStateAction<boolean | undefined>>\n disabled: boolean | undefined\n setDisabled: React.Dispatch<React.SetStateAction<boolean | undefined>>\n ariaDisabled: Booleanish | undefined\n setAriaDisabled: React.Dispatch<React.SetStateAction<Booleanish | undefined>>\n ariaInvalid: AriaAttributes['aria-invalid']\n setAriaInvalid: React.Dispatch<\n React.SetStateAction<AriaAttributes['aria-invalid']>\n >\n valid: boolean | undefined\n}\n\nexport type FormFieldProviderProps = Partial<FormFieldProps>\n\nconst FormFieldContext = createContext<FormFieldContextProps<any>>({} as any)\n\nexport const FormFieldProvider = ({\n children,\n status: customStatus,\n id: customId,\n ...restProps\n}: PropsWithChildren<FormFieldProviderProps>): JSX.Element => {\n // form field state\n const [status, setStatus] = useState<FormFieldStatus>(\n customStatus ?? 'pristine'\n )\n const [focused, setFocused] = useState(false)\n const [isFloatingLabel, setIsFloatingLabel] = useState(true)\n const [label, setLabel] = useState<React.ReactNode>(null)\n const shouldUseFloatingLabel = label !== undefined && isFloatingLabel\n\n // partials\n const autoId = useId()\n const id = customId ?? autoId\n\n const [messageId, setMessageId] = useState(`${id}-message`)\n const [helperId, setHelperId] = useState(`${id}-helper`)\n const [descriptionId, setDescriptionId] = useState(`${id}-description`)\n\n // form element\n const formElementRef = useRef<HTMLInputElement>(null)\n const [required, setRequired] = useState<boolean>()\n const [readOnly, setReadOnly] = useState<boolean>()\n const [disabled, setDisabled] = useState<boolean>()\n const [ariaDisabled, setAriaDisabled] = useState<Booleanish>()\n const [ariaInvalid, setAriaInvalid] =\n useState<AriaAttributes['aria-invalid']>()\n const [ariaDescribedBy, setAriaDescribedBy] = useState<string | undefined>('')\n const [valid, setValid] = useState<boolean | undefined>(true)\n\n useEffect(() => {\n const message = document.getElementById(messageId)\n const helper = document.getElementById(helperId)\n const description = document.getElementById(descriptionId)\n\n const ariaDescribedBy = stringAttrValue(\n // message or description\n message != null ? messageId : description != null && descriptionId,\n helper != null && helperId\n )\n\n /**\n * message + helper text\n * description + helper text\n */\n setAriaDescribedBy(ariaDescribedBy === '' ? undefined : ariaDescribedBy)\n }, [messageId, helperId, descriptionId])\n\n useEffect(() => {\n if (status === FORM_FIELD_STATUS.invalid) {\n setAriaInvalid(true)\n } else {\n setAriaInvalid(undefined)\n }\n }, [status])\n\n useEffect(() => {\n if (status === FORM_FIELD_STATUS.valid) {\n setValid(true)\n } else if (status === FORM_FIELD_STATUS.invalid) {\n setValid(false)\n } else {\n setValid(undefined)\n }\n }, [status])\n\n return (\n <FormFieldContext.Provider\n value={{\n ...restProps,\n id,\n formElementRef,\n formElementId: `${id}-form-element`,\n messageId,\n setMessageId,\n helperId,\n setHelperId,\n descriptionId,\n setDescriptionId,\n status,\n setStatus,\n focused,\n setFocused,\n isFloatingLabel,\n setIsFloatingLabel,\n label,\n setLabel,\n ariaDescribedBy,\n shouldUseFloatingLabel,\n required,\n setRequired,\n readOnly,\n setReadOnly,\n disabled,\n setDisabled,\n ariaDisabled,\n setAriaDisabled,\n ariaInvalid,\n setAriaInvalid,\n valid,\n }}\n >\n {children}\n </FormFieldContext.Provider>\n )\n}\n\nexport const useFormFieldContext = <\n T extends FormElements\n>(): FormFieldContextProps<T> => useContext(FormFieldContext)\n","import type { ComponentPropsWithRef } from 'react'\nimport { styled } from '@mirohq/design-system-stitches'\nimport { Primitive } from '@mirohq/design-system-primitive'\nimport { styles as baseInputStyles } from '@mirohq/design-system-base-input'\n\nexport const StyledFloatingLabel = styled(Primitive.label, {\n transitionProperty: 'transform, margin, top, left, font-size',\n transitionDuration: '200ms',\n transitionTimingFunction: 'cubic-bezier(0, 0, 0.2, 1)',\n position: 'absolute',\n top: 0,\n left: 0,\n zIndex: 1,\n pointerEvents: 'none',\n whiteSpace: 'nowrap',\n fontStyle: 'normal',\n lineHeight: 1.5,\n height: '0.75em',\n variants: {\n floating: {\n true: {\n top: '-$100',\n left: '$150',\n fontSize: '$150',\n color: '$text-neutrals-subtle',\n padding: '0 2px',\n backgroundColor: '$background-neutrals-container',\n },\n false: {\n fontSize: '$200',\n marginTop: '-1px', // adjust for the input's border\n ...baseInputStyles.base.placeholder,\n },\n },\n size: {\n large: {},\n 'x-large': {},\n },\n },\n compoundVariants: [\n {\n size: 'large',\n floating: false,\n css: {\n top: '$100',\n left: '$150',\n },\n },\n {\n size: 'x-large',\n floating: false,\n css: {\n top: '$150',\n // $space$250 does not exist by design but we will force it here\n left: 'calc($200 + $space$50)',\n },\n },\n ],\n defaultVariants: {\n size: 'large',\n },\n})\n\nexport type StyledFloatingLabelProps = ComponentPropsWithRef<\n typeof StyledFloatingLabel\n>\n","import React from 'react'\nimport type { ElementRef } from 'react'\n\nimport { useFormFieldContext } from './hooks/use-form-field-context'\nimport { StyledFloatingLabel } from './floating-label.styled'\nimport type { StyledFloatingLabelProps } from './floating-label.styled'\n\nexport interface FloatingLabelProps extends StyledFloatingLabelProps {}\n\nexport const FloatingLabel = React.forwardRef<\n ElementRef<typeof StyledFloatingLabel>,\n FloatingLabelProps\n>((props, forwardRef) => {\n const { isFloatingLabel, formElementId } = useFormFieldContext()\n\n return (\n <StyledFloatingLabel\n htmlFor={formElementId}\n floating={isFloatingLabel}\n {...props}\n ref={forwardRef}\n />\n )\n})\n"],"names":["ariaDescribedBy","baseInputStyles"],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -494,18 +494,12 @@ declare const StyledFloatingLabel: React.ForwardRefExoticComponent<Omit<Omit<_mi
494
494
  _hover: (css: _stitches_react_types_css_util.CSSProperties) => {
495
495
  '&:hover, &[data-hovered]': _stitches_react_types_css_util.CSSProperties;
496
496
  };
497
- }>>>, "readOnly" | "disabled" | "ariaDisabled" | "size" | "floating"> & _stitches_react_types_styled_component.TransformProps<{
497
+ }>>>, "size" | "floating"> & _stitches_react_types_styled_component.TransformProps<{
498
498
  floating?: boolean | "false" | "true" | undefined;
499
499
  size?: "large" | "x-large" | undefined;
500
- readOnly?: boolean | "true" | undefined;
501
- disabled?: boolean | "true" | undefined;
502
- ariaDisabled?: boolean | "false" | "true" | undefined;
503
500
  }, {}> & _mirohq_design_system_stitches.CustomStylesProps, "ref"> & React.RefAttributes<HTMLLabelElement>> & _mirohq_design_system_stitches.StitchesInternals<React.ForwardRefExoticComponent<_mirohq_design_system_primitive.PrimitiveProps<"label">>, {
504
501
  floating?: boolean | "false" | "true" | undefined;
505
502
  size?: "large" | "x-large" | undefined;
506
- readOnly?: boolean | "true" | undefined;
507
- disabled?: boolean | "true" | undefined;
508
- ariaDisabled?: boolean | "false" | "true" | undefined;
509
503
  }, {}>;
510
504
  declare type StyledFloatingLabelProps = ComponentPropsWithRef<typeof StyledFloatingLabel>;
511
505
 
@@ -522,11 +516,16 @@ declare const FORM_FIELD_STATUS: Readonly<{
522
516
  }>;
523
517
  declare type FormFieldStatus = keyof typeof FORM_FIELD_STATUS;
524
518
 
519
+ declare type FormElements = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;
525
520
  interface FormFieldProps {
521
+ /**
522
+ * Field status
523
+ * @default "pristine"
524
+ */
526
525
  status?: FormFieldStatus;
527
526
  id?: string;
528
527
  }
529
- interface FormFieldContextProps extends FormFieldProps {
528
+ interface FormFieldContextProps<FormElementRef extends FormElements> extends FormFieldProps {
530
529
  setStatus: React__default.Dispatch<React__default.SetStateAction<FormFieldStatus>>;
531
530
  isFloatingLabel: boolean;
532
531
  setIsFloatingLabel: React__default.Dispatch<React__default.SetStateAction<boolean>>;
@@ -541,7 +540,7 @@ interface FormFieldContextProps extends FormFieldProps {
541
540
  descriptionId: string;
542
541
  setDescriptionId: React__default.Dispatch<React__default.SetStateAction<string>>;
543
542
  formElementId: string;
544
- formElementRef: React__default.RefObject<HTMLInputElement>;
543
+ formElementRef: React__default.MutableRefObject<FormElementRef>;
545
544
  ariaDescribedBy: string | undefined;
546
545
  shouldUseFloatingLabel: boolean;
547
546
  required: boolean | undefined;
@@ -558,6 +557,30 @@ interface FormFieldContextProps extends FormFieldProps {
558
557
  }
559
558
  declare type FormFieldProviderProps = Partial<FormFieldProps>;
560
559
  declare const FormFieldProvider: ({ children, status: customStatus, id: customId, ...restProps }: PropsWithChildren<FormFieldProviderProps>) => JSX.Element;
561
- declare const useFormFieldContext: () => FormFieldContextProps;
560
+ declare const useFormFieldContext: <T extends FormElements>() => FormFieldContextProps<T>;
562
561
 
563
- export { FORM_FIELD_STATUS, FloatingLabel, FloatingLabelProps, FormFieldProvider, FormFieldProviderProps, FormFieldStatus, useFormFieldContext };
562
+ interface FormElementProps {
563
+ /**
564
+ * Prevents the user from interacting with the form element.
565
+ */
566
+ disabled?: boolean;
567
+ /**
568
+ * Prevents the user from interacting with the form element.
569
+ * But still allows the form element to be focused.
570
+ */
571
+ 'aria-disabled'?: Booleanish;
572
+ /**
573
+ * Prevents the user from modifying the form element.
574
+ */
575
+ readOnly?: boolean;
576
+ /**
577
+ * Indicates whether the form element's value is valid.
578
+ */
579
+ valid?: boolean;
580
+ /**
581
+ * Indicates whether the form element is required.
582
+ */
583
+ required?: boolean;
584
+ }
585
+
586
+ export { FORM_FIELD_STATUS, FloatingLabel, FloatingLabelProps, FormElementProps, FormFieldProvider, FormFieldProviderProps, FormFieldStatus, useFormFieldContext };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mirohq/design-system-base-form",
3
- "version": "0.1.0-forms.0",
3
+ "version": "0.1.0-forms.2",
4
4
  "description": "",
5
5
  "author": "Miro",
6
6
  "source": "src/index.ts",
@@ -26,11 +26,12 @@
26
26
  "react": "^16.14 || ^17 || ^18"
27
27
  },
28
28
  "dependencies": {
29
- "@mirohq/design-system-base-input": "^0.1.0-forms.2",
30
- "@mirohq/design-system-primitive": "^1.1.2-forms.0",
31
- "@mirohq/design-system-stitches": "^2.6.0",
29
+ "@mirohq/design-system-base-input": "^0.0.3-forms.3",
30
+ "@mirohq/design-system-primitive": "^1.1.2-forms.1",
32
31
  "@mirohq/design-system-types": "^0.6.2",
33
- "@mirohq/design-system-use-id": "^0.1.1-forms.0"
32
+ "@mirohq/design-system-use-id": "^0.1.1-forms.1",
33
+ "@mirohq/design-system-utils": "^0.15.0-forms.2",
34
+ "@mirohq/design-system-stitches": "^2.6.0"
34
35
  },
35
36
  "scripts": {
36
37
  "build": "rollup -c ../../../../rollup.config.js",