@fiscozen/input 0.1.15 → 0.1.16-beta.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiscozen/input",
3
- "version": "0.1.15",
3
+ "version": "0.1.16-beta.1",
4
4
  "description": "Design System Input component",
5
5
  "main": "src/index.ts",
6
6
  "type": "module",
@@ -9,8 +9,9 @@
9
9
  "peerDependencies": {
10
10
  "tailwindcss": "^3.4.1",
11
11
  "vue": "^3.4.13",
12
+ "@fiscozen/button": "^0.1.12-beta.1",
12
13
  "@fiscozen/composables": "^0.1.36",
13
- "@fiscozen/icons": "^0.1.24"
14
+ "@fiscozen/icons": "^0.1.28"
14
15
  },
15
16
  "devDependencies": {
16
17
  "@rushstack/eslint-patch": "^1.3.3",
@@ -29,8 +30,8 @@
29
30
  "vitest": "^1.2.0",
30
31
  "vue-tsc": "^1.8.25",
31
32
  "@fiscozen/eslint-config": "^0.1.0",
32
- "@fiscozen/prettier-config": "^0.1.0",
33
- "@fiscozen/tsconfig": "^0.1.0"
33
+ "@fiscozen/tsconfig": "^0.1.0",
34
+ "@fiscozen/prettier-config": "^0.1.0"
34
35
  },
35
36
  "license": "MIT",
36
37
  "scripts": {
package/src/FzInput.vue CHANGED
@@ -24,23 +24,26 @@
24
24
  :class="leftIconClass"
25
25
  />
26
26
  </slot>
27
- <input
28
- :type="type"
29
- :required="required ? required : false"
30
- :disabled="disabled"
31
- :readonly="readonly"
32
- :placeholder="placeholder"
33
- v-model="model"
34
- :id="uniqueId"
35
- ref="inputRef"
36
- :class="[staticInputClass]"
37
- :pattern="pattern"
38
- :name
39
- :maxlength
40
- @blur="(e) => $emit('blur', e)"
41
- @focus="(e) => $emit('focus', e)"
42
- @paste="(e) => $emit('paste', e)"
43
- />
27
+ <div class="flex flex-col space-around min-w-0">
28
+ <span v-if="!showNormalPlaceholder" class="text-xs text-gray-300 grow-0 overflow-hidden text-ellipsis whitespace-nowrap">{{ placeholder }}</span>
29
+ <input
30
+ :type="type"
31
+ :required="required ? required : false"
32
+ :disabled="disabled"
33
+ :readonly="readonly"
34
+ :placeholder="showNormalPlaceholder ? placeholder : ''"
35
+ v-model="model"
36
+ :id="uniqueId"
37
+ ref="inputRef"
38
+ :class="[staticInputClass, computedInputClass]"
39
+ :pattern="pattern"
40
+ :name
41
+ :maxlength
42
+ @blur="(e) => $emit('blur', e)"
43
+ @focus="(e) => $emit('focus', e)"
44
+ @paste="(e) => $emit('paste', e)"
45
+ />
46
+ </div>
44
47
  <slot name="right-icon">
45
48
  <FzIcon
46
49
  v-if="valid"
@@ -49,13 +52,22 @@
49
52
  class="text-semantic-success"
50
53
  />
51
54
  <FzIcon
52
- v-if="rightIcon"
55
+ v-if="rightIcon && !rightIconButton"
53
56
  :name="rightIcon"
54
57
  :size="size"
55
58
  :variant="rightIconVariant"
56
59
  @click.stop="emit('fzinput:right-icon-click')"
57
60
  :class="rightIconClass"
58
61
  />
62
+ <FzIconButton
63
+ v-if="rightIcon && rightIconButton"
64
+ :iconName="rightIcon"
65
+ :size="mappedSize"
66
+ :iconVariant="rightIconVariant"
67
+ :variant="disabled ? 'invisible' : rightIconButtonVariant"
68
+ @click.stop="emit('fzinput:right-icon-click')"
69
+ :class="[{'bg-grey-100 !text-gray-300': disabled}, rightIconClass]"
70
+ />
59
71
  </slot>
60
72
  </div>
61
73
  <div
@@ -83,15 +95,18 @@
83
95
  </template>
84
96
 
85
97
  <script setup lang="ts">
86
- import { Ref, ref } from "vue";
98
+ import { computed, toRefs, Ref, ref } from "vue";
87
99
  import { FzInputProps } from "./types";
88
100
  import { FzIcon } from "@fiscozen/icons";
101
+ import { FzIconButton } from "@fiscozen/button";
89
102
  import useInputStyle from "./useInputStyle";
90
103
 
91
104
  const props = withDefaults(defineProps<FzInputProps>(), {
92
105
  size: "md",
93
106
  error: false,
94
107
  type: "text",
108
+ rightIconButtonVariant: 'invisible',
109
+ variant: 'normal'
95
110
  });
96
111
 
97
112
  const model = defineModel();
@@ -104,10 +119,24 @@ const {
104
119
  computedContainerClass,
105
120
  computedLabelClass,
106
121
  staticInputClass,
122
+ computedInputClass,
107
123
  computedHelpClass,
108
124
  computedErrorClass,
109
125
  containerWidth,
110
- } = useInputStyle(props, containerRef);
126
+ showNormalPlaceholder
127
+ } = useInputStyle(toRefs(props), containerRef, model);
128
+
129
+
130
+ const sizeMap = {
131
+ xl: 'lg',
132
+ lg: 'md',
133
+ md: 'sm',
134
+ sm: 'xs',
135
+ }
136
+
137
+ const mappedSize = computed(() => {
138
+ return sizeMap[props.size];
139
+ });
111
140
 
112
141
  const emit = defineEmits([
113
142
  "input",
package/src/types.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { IconVariant } from "@fiscozen/icons";
1
+ import { IconButtonVariant } from "@fiscozen/button";
2
+ import { IconSize , IconVariant } from "@fiscozen/icons";
2
3
 
3
4
  type FzInputProps = {
4
5
  /**
@@ -13,6 +14,10 @@ type FzInputProps = {
13
14
  * The placeholder displayed in the input
14
15
  */
15
16
  placeholder?: string;
17
+ /**
18
+ * Secondary - floating like placeholder
19
+ */
20
+ secondaryPlaceholder?: string;
16
21
  /**
17
22
  * If set to true, the input is required
18
23
  */
@@ -33,14 +38,30 @@ type FzInputProps = {
33
38
  * Left icon variant
34
39
  */
35
40
  leftIconVariant?: IconVariant;
41
+ /**
42
+ * Left icon button variant
43
+ */
44
+ leftIconButtonVariant?: IconButtonVariant;
36
45
  /**
37
46
  * Right icon name
38
47
  */
39
48
  rightIcon?: string;
49
+ /**
50
+ * Right icon name
51
+ */
52
+ rightIconSize?: IconSize;
40
53
  /**
41
54
  * Right icon variant
42
55
  */
43
56
  rightIconVariant?: IconVariant;
57
+ /**
58
+ * Right icon button vs normal icon
59
+ */
60
+ rightIconButton?: boolean;
61
+ /**
62
+ * Right icon button variant
63
+ */
64
+ rightIconButtonVariant?: IconButtonVariant;
44
65
  /**
45
66
  * The input type
46
67
  */
@@ -49,6 +70,10 @@ type FzInputProps = {
49
70
  * If set to true, the input is valid
50
71
  */
51
72
  valid?: boolean;
73
+ /**
74
+ * Input variant
75
+ */
76
+ variant?: 'normal' | 'floating-label';
52
77
  /**
53
78
  * Pattern to validate the input
54
79
  */
@@ -1,9 +1,10 @@
1
- import { computed, Ref } from "vue";
1
+ import { computed, ToRefs, Ref } from "vue";
2
2
  import { FzInputProps } from "./types";
3
3
 
4
4
  export default function useInputStyle(
5
- props: FzInputProps,
5
+ props: ToRefs<FzInputProps>,
6
6
  container: Ref<HTMLElement | null>,
7
+ model: Ref<string>
7
8
  ) {
8
9
  const containerWidth = computed(() =>
9
10
  container.value ? `${container.value.clientWidth}px` : "auto",
@@ -15,37 +16,53 @@ export default function useInputStyle(
15
16
  lg: "h-40 text-lg",
16
17
  };
17
18
 
18
- const staticContainerClass = `flex justify-between w-full items-center px-10 border-1 rounded gap-8 text-left has-[:focus]:border-blue-600`;
19
+ const staticContainerClass = `flex justify-between w-full items-center px-10 border-1 rounded gap-8 text-left has-[:focus]:border-blue-600 relative`;
19
20
 
20
21
  const computedContainerClass = computed(() => [
21
- mapContainerClass[props.size!],
22
+ props.variant?.value === 'normal' ? mapContainerClass[props.size?.value!] : 'h-40 pr-6',
22
23
  evaluateProps(),
23
24
  ]);
24
25
 
25
26
  const computedLabelClass = computed(() => [
26
- props.disabled ? "text-grey-300" : "text-core-black",
27
+ props.disabled?.value ? "text-grey-300" : "text-core-black",
27
28
  ]);
28
29
 
29
30
  const staticInputClass = `peer w-full bg-transparent border-0 focus:outline-none cursor-[inherit] focus:ring-0 truncate`;
30
31
 
32
+ const textSizeMap = {
33
+ xl: 'text-lg',
34
+ lg: 'text-base',
35
+ md: 'text-sm',
36
+ sm: 'text-xs'
37
+ }
38
+
39
+ const showNormalPlaceholder = computed(() => {
40
+ return !(props.variant?.value === 'floating-label') ||
41
+ ((props.variant?.value === 'floating-label') && !model.value)
42
+ });
43
+
44
+ const computedInputClass = computed(() => [
45
+ props.variant?.value === 'floating-label' ? textSizeMap[props.size?.value] : '',
46
+ ]);
47
+
31
48
  const computedHelpClass = computed(() => [
32
- props.size === "sm" ? "text-xs" : "",
33
- props.size === "md" ? "text-sm" : "",
34
- props.size === "lg" ? "text-base" : "",
35
- props.disabled ? "text-grey-300" : "text-grey-500",
49
+ props.size?.value === "sm" ? "text-xs" : "",
50
+ props.size?.value === "md" ? "text-sm" : "",
51
+ props.size?.value === "lg" ? "text-base" : "",
52
+ props.disabled?.value ? "text-grey-300" : "text-grey-500",
36
53
  ]);
37
54
  const computedErrorClass = computed(() => [
38
- props.size === "sm" ? "text-xs" : "",
39
- props.size === "md" ? "text-sm" : "",
40
- props.size === "lg" ? "text-base" : "",
41
- props.disabled ? "text-grey-300" : "text-core-black",
55
+ props.size?.value === "sm" ? "text-xs" : "",
56
+ props.size?.value === "md" ? "text-sm" : "",
57
+ props.size?.value === "lg" ? "text-base" : "",
58
+ props.disabled?.value ? "text-grey-300" : "text-core-black",
42
59
  ]);
43
60
 
44
61
  const evaluateProps = () => {
45
62
  switch (true) {
46
- case props.disabled:
63
+ case props.disabled?.value:
47
64
  return "bg-grey-100 border-grey-100 text-grey-300 cursor-not-allowed";
48
- case props.error:
65
+ case props.error?.value:
49
66
  return "border-semantic-error bg-white text-core-black cursor-text";
50
67
  default:
51
68
  return "border-grey-300 bg-white text-core-black cursor-text";
@@ -57,8 +74,10 @@ export default function useInputStyle(
57
74
  computedContainerClass,
58
75
  computedLabelClass,
59
76
  staticInputClass,
77
+ computedInputClass,
60
78
  computedHelpClass,
61
79
  computedErrorClass,
62
80
  containerWidth,
81
+ showNormalPlaceholder
63
82
  };
64
83
  }