@fiscozen/input 3.0.2 → 3.0.3

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/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@fiscozen/input",
3
- "version": "3.0.2",
3
+ "version": "3.0.3",
4
4
  "description": "Design System Input component",
5
5
  "main": "src/index.ts",
6
6
  "type": "module",
7
7
  "keywords": [],
8
8
  "author": "Cristian Barraco",
9
9
  "dependencies": {
10
- "@fiscozen/alert": "3.0.0",
10
+ "@fiscozen/button": "3.0.0",
11
11
  "@fiscozen/composables": "1.0.3",
12
- "@fiscozen/button": "3.0.0"
12
+ "@fiscozen/alert": "3.0.0"
13
13
  },
14
14
  "peerDependencies": {
15
15
  "tailwindcss": "^3.4.1",
@@ -78,7 +78,7 @@ const getEmptyValue = (): number | null | undefined => {
78
78
  */
79
79
  const getEmptyDisplayValue = (
80
80
  isEmptyValueZero: boolean,
81
- isCurrentlyFocused: boolean
81
+ isCurrentlyFocused: boolean,
82
82
  ): string => {
83
83
  if (isEmptyValueZero) {
84
84
  // During typing, show empty string. Formatting happens on blur
@@ -327,7 +327,7 @@ const handleBlur = () => {
327
327
  // Display empty value (formatted zero if zeroOnEmpty is true, empty string otherwise)
328
328
  fzInputModel.value = getEmptyDisplayValue(
329
329
  expectedEmptyValue === 0,
330
- false // Not focused during blur
330
+ false, // Not focused during blur
331
331
  );
332
332
  return;
333
333
  }
@@ -395,7 +395,7 @@ const handleFocus = () => {
395
395
  * @returns Normalized number value, undefined, or null
396
396
  */
397
397
  const normalizeModelValue = (
398
- value: number | string | undefined | null
398
+ value: number | string | undefined | null,
399
399
  ): number | undefined | null => {
400
400
  if (value === undefined || value === null || value === "") {
401
401
  return value === null ? null : undefined;
@@ -406,7 +406,7 @@ const normalizeModelValue = (
406
406
  if (typeof value === "string") {
407
407
  console.warn(
408
408
  "[FzCurrencyInput] String values in v-model are deprecated. Please use number instead. " +
409
- `Received: "${value}". This will be parsed to a number for retrocompatibility, but string support may be removed in a future version.`
409
+ `Received: "${value}". This will be parsed to a number for retrocompatibility, but string support may be removed in a future version.`,
410
410
  );
411
411
  const parsed = parse(value);
412
412
  return isNaN(parsed) ? undefined : parsed;
@@ -512,7 +512,7 @@ onMounted(() => {
512
512
  // Display empty value (formatted zero if zeroOnEmpty is true, empty string otherwise)
513
513
  fzInputModel.value = getEmptyDisplayValue(
514
514
  expectedEmptyValue === 0,
515
- false // Not focused during mount
515
+ false, // Not focused during mount
516
516
  );
517
517
  return;
518
518
  }
@@ -585,7 +585,7 @@ onMounted(() => {
585
585
  // Display empty value (formatted zero if zeroOnEmpty is true, empty string otherwise)
586
586
  fzInputModel.value = getEmptyDisplayValue(
587
587
  emptyValue === 0,
588
- false // Not focused during mount
588
+ false, // Not focused during mount
589
589
  );
590
590
  }
591
591
  return;
@@ -621,7 +621,7 @@ watch(
621
621
  // Display empty value (formatted zero if zeroOnEmpty is true, empty string otherwise)
622
622
  fzInputModel.value = getEmptyDisplayValue(
623
623
  expectedEmptyValue === 0,
624
- isFocused.value
624
+ isFocused.value,
625
625
  );
626
626
  return;
627
627
  }
@@ -705,12 +705,12 @@ watch(
705
705
  // Display empty value (formatted zero if zeroOnEmpty is true, empty string otherwise)
706
706
  fzInputModel.value = getEmptyDisplayValue(
707
707
  emptyValue === 0,
708
- isFocused.value
708
+ isFocused.value,
709
709
  );
710
710
  }
711
711
  return;
712
712
  }
713
- }
713
+ },
714
714
  );
715
715
 
716
716
  defineExpose({
@@ -731,10 +731,10 @@ defineExpose({
731
731
  @blur="handleBlur"
732
732
  @paste="handlePaste"
733
733
  >
734
- <template #label>
734
+ <template v-if="$slots.label" #label>
735
735
  <slot name="label"></slot>
736
736
  </template>
737
- <template #left-icon>
737
+ <template v-if="$slots['left-icon']" #left-icon>
738
738
  <slot name="left-icon"></slot>
739
739
  </template>
740
740
  <template #right-icon>
@@ -786,10 +786,10 @@ defineExpose({
786
786
  </div>
787
787
  </div>
788
788
  </template>
789
- <template #helpText>
789
+ <template v-if="$slots.helpText" #helpText>
790
790
  <slot name="helpText"></slot>
791
791
  </template>
792
- <template #errorMessage>
792
+ <template v-if="$slots.errorMessage" #errorMessage>
793
793
  <slot name="errorMessage"></slot>
794
794
  </template>
795
795
  </FzInput>
@@ -1588,5 +1588,109 @@ describe('FzCurrencyInput', () => {
1588
1588
  })
1589
1589
  })
1590
1590
  })
1591
+
1592
+ describe('Slot forwarding', () => {
1593
+ it('should not render empty help text span when helpText slot is not provided', async () => {
1594
+ const wrapper = mount(FzCurrencyInput, {
1595
+ props: {
1596
+ label: 'Label',
1597
+ modelValue: 10,
1598
+ },
1599
+ })
1600
+
1601
+ await wrapper.vm.$nextTick()
1602
+
1603
+ const helpSpan = wrapper.find(`[id$="-help"]`)
1604
+ expect(helpSpan.exists()).toBe(false)
1605
+ })
1606
+
1607
+ it('should render help text span when helpText slot is provided', async () => {
1608
+ const wrapper = mount(FzCurrencyInput, {
1609
+ props: {
1610
+ label: 'Label',
1611
+ modelValue: 10,
1612
+ },
1613
+ slots: {
1614
+ helpText: 'Enter an amount',
1615
+ },
1616
+ })
1617
+
1618
+ await wrapper.vm.$nextTick()
1619
+
1620
+ const helpSpan = wrapper.find(`[id$="-help"]`)
1621
+ expect(helpSpan.exists()).toBe(true)
1622
+ expect(helpSpan.text()).toContain('Enter an amount')
1623
+ })
1624
+
1625
+ it('should render label from label prop when label slot is not provided', async () => {
1626
+ const wrapper = mount(FzCurrencyInput, {
1627
+ props: {
1628
+ label: 'Amount',
1629
+ modelValue: 10,
1630
+ },
1631
+ })
1632
+
1633
+ await wrapper.vm.$nextTick()
1634
+
1635
+ const label = wrapper.find('label')
1636
+ expect(label.exists()).toBe(true)
1637
+ expect(label.text()).toContain('Amount')
1638
+ })
1639
+
1640
+ it('should render custom label slot instead of label prop', async () => {
1641
+ const wrapper = mount(FzCurrencyInput, {
1642
+ props: {
1643
+ label: 'Amount',
1644
+ modelValue: 10,
1645
+ },
1646
+ slots: {
1647
+ label: '<strong>Custom Label</strong>',
1648
+ },
1649
+ })
1650
+
1651
+ await wrapper.vm.$nextTick()
1652
+
1653
+ const strong = wrapper.find('strong')
1654
+ expect(strong.exists()).toBe(true)
1655
+ expect(strong.text()).toBe('Custom Label')
1656
+
1657
+ const defaultLabel = wrapper.find('label')
1658
+ expect(defaultLabel.exists()).toBe(false)
1659
+ })
1660
+
1661
+ it('should not render error message container when errorMessage slot is not provided', async () => {
1662
+ const wrapper = mount(FzCurrencyInput, {
1663
+ props: {
1664
+ label: 'Label',
1665
+ modelValue: 10,
1666
+ error: true,
1667
+ },
1668
+ })
1669
+
1670
+ await wrapper.vm.$nextTick()
1671
+
1672
+ const errorContainer = wrapper.find('[role="alert"]')
1673
+ expect(errorContainer.exists()).toBe(false)
1674
+ })
1675
+
1676
+ it('should render error message when error is true and errorMessage slot is provided', async () => {
1677
+ const wrapper = mount(FzCurrencyInput, {
1678
+ props: {
1679
+ label: 'Label',
1680
+ modelValue: 10,
1681
+ error: true,
1682
+ },
1683
+ slots: {
1684
+ errorMessage: 'Invalid amount',
1685
+ },
1686
+ })
1687
+
1688
+ await wrapper.vm.$nextTick()
1689
+
1690
+ const errorContainer = wrapper.find('[role="alert"]')
1691
+ expect(errorContainer.exists()).toBe(true)
1692
+ expect(errorContainer.text()).toContain('Invalid amount')
1693
+ })
1694
+ })
1591
1695
  })
1592
1696