@ciromaciel/auth-react 1.6.0 → 1.7.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.
package/README.md CHANGED
@@ -160,6 +160,16 @@ organization and on which plan, then one list of actions with "Sair" last.
160
160
  thing.
161
161
  - `items` are your app's own rows, passed as data (`{ id, label, icon, onClick }`), shown in their
162
162
  own group after billing. The component takes no JSX, so every app's card keeps the same shape.
163
+ A row may add `description` (one line saying what it does) and `tone: 'danger'` (red, for what
164
+ cannot be undone); `itemsLabel` titles the group:
165
+
166
+ ```jsx
167
+ itemsLabel="Seus dados"
168
+ items={[
169
+ { id: 'export', label: 'Exportar', description: 'Uma cópia de tudo, em JSON', icon: IconDownload, onClick: exportAll },
170
+ { id: 'erase', label: 'Apagar tudo', description: 'Sem volta', tone: 'danger', icon: IconTrash, onClick: eraseAll },
171
+ ]}
172
+ ```
163
173
  - `plan` and `organization` draw the context strip; leave them out and it is not drawn.
164
174
  `limit: null` hides the usage bar.
165
175
  - The strip informs; "Assinatura" is the way to billing. The strip adds a "Fazer upgrade"
package/dist/index.esm.js CHANGED
@@ -4480,6 +4480,8 @@ const UPGRADE_THRESHOLD = 0.8;
4480
4480
  * @property {string} [id] - Stable key
4481
4481
  * @property {string} label - The row's text
4482
4482
  * @property {Function} [icon] - A Tabler icon component
4483
+ * @property {string} [description] - One line under the label, saying what the action does
4484
+ * @property {'danger'} [tone] - For what cannot be undone: red label and icon
4483
4485
  * @property {Function} onClick
4484
4486
  *
4485
4487
  * @typedef {Object} UserInformationPlan
@@ -4506,6 +4508,7 @@ const UPGRADE_THRESHOLD = 0.8;
4506
4508
  * @param {Function} [props.onAccountClick]
4507
4509
  * @param {Function} [props.onBillingClick]
4508
4510
  * @param {UserInformationItem[]} [props.items] - The panel's own rows, shown in their own group
4511
+ * @param {string} [props.itemsLabel] - A title for that group ("Seus dados"); without it, none
4509
4512
  * @param {UserInformationPlan} [props.plan] - The plan strip; omitted, the strip is not drawn
4510
4513
  * @param {UserInformationOrganization} [props.organization] - Where the person is acting
4511
4514
  * @param {boolean} [props.branded=true] - The footer: "Protegido por Auth" and the terms link
@@ -4521,6 +4524,7 @@ function UserInformation({
4521
4524
  onAccountClick,
4522
4525
  onBillingClick,
4523
4526
  items = [],
4527
+ itemsLabel,
4524
4528
  plan,
4525
4529
  organization,
4526
4530
  branded = true,
@@ -4618,6 +4622,7 @@ function UserInformation({
4618
4622
  hasDivider: !organization?.name && !plan
4619
4623
  }), panelRows.length > 0 && /*#__PURE__*/jsx(RowGroup, {
4620
4624
  rows: panelRows,
4625
+ label: itemsLabel,
4621
4626
  hasDivider: true
4622
4627
  }), signOut && /*#__PURE__*/jsx(RowGroup, {
4623
4628
  rows: [{
@@ -4667,6 +4672,9 @@ function UserInformation({
4667
4672
  });
4668
4673
  }
4669
4674
 
4675
+ // "12.400 de 60.000 páginas", not "12400 de 60000": the History counts pages in the thousands.
4676
+ const formatCount = value => Number(value).toLocaleString('pt-BR');
4677
+
4670
4678
  /** The organization, the role and the plan's usage, on the alternate surface. */
4671
4679
  function ContextStrip({
4672
4680
  organization,
@@ -4766,7 +4774,7 @@ function ContextStrip({
4766
4774
  fz: 12,
4767
4775
  fw: isFull ? 700 : 500,
4768
4776
  c: isFull ? 'red.8' : 'gray.6',
4769
- children: `${plan.used} de ${plan.limit}${plan.unit ? ` ${plan.unit}` : ''}${isFull && !limitNoticeOnTop ? ' · limite atingido' : ''}`
4777
+ children: `${formatCount(plan.used)} de ${formatCount(plan.limit)}${plan.unit ? ` ${plan.unit}` : ''}${isFull && !limitNoticeOnTop ? ' · limite atingido' : ''}`
4770
4778
  }), showsInvite && /*#__PURE__*/jsx(UnstyledButton, {
4771
4779
  onClick: plan.onClick,
4772
4780
  fz: 11,
@@ -4789,24 +4797,59 @@ function ContextStrip({
4789
4797
  }
4790
4798
  function RowGroup({
4791
4799
  rows,
4800
+ label,
4792
4801
  hasDivider
4793
4802
  }) {
4794
- return /*#__PURE__*/jsx(Stack, {
4803
+ return /*#__PURE__*/jsxs(Stack, {
4795
4804
  gap: 0,
4796
4805
  p: 6,
4806
+ role: label ? 'group' : undefined,
4807
+ "aria-label": label || undefined,
4797
4808
  style: hasDivider ? {
4798
4809
  borderTop: '1px solid var(--mantine-color-gray-2)'
4799
4810
  } : undefined,
4800
- children: rows.map(row => /*#__PURE__*/jsx(Row, {
4811
+ children: [label && /*#__PURE__*/jsx(Text, {
4812
+ "aria-hidden": true,
4813
+ fz: 11,
4814
+ fw: 800,
4815
+ tt: "uppercase",
4816
+ lts: "1.5px",
4817
+ c: "gray.4",
4818
+ px: 10,
4819
+ pt: 6,
4820
+ pb: 2,
4821
+ children: label
4822
+ }), rows.map(row => /*#__PURE__*/jsx(Row, {
4801
4823
  ...row
4802
- }, row.id || row.label))
4824
+ }, row.id || row.label))]
4803
4825
  });
4804
4826
  }
4827
+
4828
+ /*
4829
+ * A panel's row may carry a line saying what it does and, for what cannot be
4830
+ * undone, the danger tone — still as data, so every card keeps one shape. The
4831
+ * History needed both: "Apagar tudo" looked exactly like "Exportar".
4832
+ */
4833
+ const ROW_TONES = {
4834
+ default: {
4835
+ text: 'gray.9',
4836
+ icon: 'var(--mantine-color-gray-5)',
4837
+ hover: 'var(--mantine-color-gray-1)'
4838
+ },
4839
+ danger: {
4840
+ text: 'red.8',
4841
+ icon: 'var(--mantine-color-red-8)',
4842
+ hover: 'var(--mantine-color-red-0)'
4843
+ }
4844
+ };
4805
4845
  function Row({
4806
4846
  label,
4847
+ description,
4848
+ tone,
4807
4849
  icon: Icon,
4808
4850
  onClick
4809
4851
  }) {
4852
+ const look = ROW_TONES[tone] || ROW_TONES.default;
4810
4853
  return /*#__PURE__*/jsxs(UnstyledButton, {
4811
4854
  role: "menuitem",
4812
4855
  onClick: onClick,
@@ -4815,7 +4858,7 @@ function Row({
4815
4858
  w: "100%",
4816
4859
  style: {
4817
4860
  display: 'flex',
4818
- alignItems: 'center',
4861
+ alignItems: description ? 'flex-start' : 'center',
4819
4862
  gap: 10,
4820
4863
  borderRadius: 0
4821
4864
  }
@@ -4823,23 +4866,35 @@ function Row({
4823
4866
  * Hover and keyboard focus share the same surface: a row reached
4824
4867
  * with the arrows must look exactly like the one under the mouse.
4825
4868
  */,
4826
- onMouseEnter: event => event.currentTarget.style.background = 'var(--mantine-color-gray-1)',
4869
+ onMouseEnter: event => event.currentTarget.style.background = look.hover,
4827
4870
  onMouseLeave: event => event.currentTarget.style.background = 'transparent',
4828
- onFocus: event => event.currentTarget.style.background = 'var(--mantine-color-gray-1)',
4871
+ onFocus: event => event.currentTarget.style.background = look.hover,
4829
4872
  onBlur: event => event.currentTarget.style.background = 'transparent',
4830
4873
  children: [Icon && /*#__PURE__*/jsx(Icon, {
4831
4874
  size: 16,
4832
4875
  stroke: 1.5,
4833
4876
  style: {
4834
4877
  flex: 'none',
4835
- color: 'var(--mantine-color-gray-5)'
4878
+ color: look.icon,
4879
+ marginTop: description ? 1 : 0
4836
4880
  }
4837
- }), /*#__PURE__*/jsx(Text, {
4838
- fz: 12,
4839
- fw: 500,
4840
- c: "gray.9",
4841
- truncate: "end",
4842
- children: label
4881
+ }), /*#__PURE__*/jsxs(Box, {
4882
+ style: {
4883
+ minWidth: 0
4884
+ },
4885
+ children: [/*#__PURE__*/jsx(Text, {
4886
+ fz: 12,
4887
+ fw: 500,
4888
+ c: look.text,
4889
+ truncate: "end",
4890
+ children: label
4891
+ }), description && /*#__PURE__*/jsx(Text, {
4892
+ fz: 12,
4893
+ fw: 500,
4894
+ c: "gray.5",
4895
+ lh: 1.4,
4896
+ children: description
4897
+ })]
4843
4898
  })]
4844
4899
  });
4845
4900
  }