fn-input 0.0.6 → 0.0.8

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.
@@ -1,3 +1,5 @@
1
+ import { InjectionToken } from '@angular/core';
2
+ export const FN_TOAST_SERVICE = new InjectionToken('FN_TOAST_SERVICE');
1
3
  export const DEFAULT_CURRENCY_META = [
2
4
  { code: 'USD', locale: 'en-US', symbol: '$', digit: '1.2-2' },
3
5
  { code: 'MYR', locale: 'en-MY', symbol: 'RM', digit: '1.2-2' },
@@ -7,4 +9,4 @@ export const DEFAULT_CURRENCY_META = [
7
9
  { code: 'CNY', locale: 'zh-CN', symbol: '¥', digit: '1.2-2' },
8
10
  { code: 'INR', locale: 'en-IN', symbol: '₹', digit: '1.2-2' },
9
11
  ];
10
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm4taW5wdXQudHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9mbi1pbnB1dC9zcmMvbGliL2ZuLWlucHV0LnR5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQXFJQSxNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRztJQUNuQyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUU7SUFDN0QsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFO0lBQzlELEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRTtJQUM3RCxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUU7SUFDN0QsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFO0lBQzdELEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRTtJQUM3RCxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUU7Q0FDOUQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFZhbGlkYXRvckZuIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5cclxuZXhwb3J0IHR5cGUgVHlwZUljb25WYXJpYW50ID0gJ0NvbG91cicgfCAnRHVvdG9uZScgfCAnRmlsbCcgfCAnTGluZSc7XHJcbmV4cG9ydCB0eXBlIFR5cGVJY29uU2l6ZSA9IDEwIHwgMTYgfCAyMCB8IDI0IHwgMzIgfCA0ODtcclxuXHJcbmV4cG9ydCB0eXBlIFR5cGVMYWJlbFZhcmlhbnQgPVxyXG4gIHwgJ2gxJ1xyXG4gIHwgJ2gxQm9sZCdcclxuICB8ICdoMidcclxuICB8ICdoMkJvbGQnXHJcbiAgfCAnaDMnXHJcbiAgfCAnaDNCb2xkJ1xyXG4gIHwgJ3AxJ1xyXG4gIHwgJ3AxQm9sZCdcclxuICB8ICdwMidcclxuICB8ICdwMkJvbGQnXHJcbiAgfCAncDMnXHJcbiAgfCAncDNCb2xkJ1xyXG4gIHwgJ3A0J1xyXG4gIHwgJ3A0Qm9sZCdcclxuICB8ICdpbnRlcmFjdGlvbkxhcmdlJ1xyXG4gIHwgJ2ludGVyYWN0aW9uTGFyZ2VCb2xkJ1xyXG4gIHwgJ2ludGVyYWN0aW9uTWVkaXVtJ1xyXG4gIHwgJ2ludGVyYWN0aW9uTWVkaXVtQm9sZCdcclxuICB8ICdpbnRlcmFjdGlvblNtYWxsJ1xyXG4gIHwgJ2ludGVyYWN0aW9uU21hbGxCb2xkJ1xyXG4gIHwgJ2F2YXRhckxhYmVsJztcclxuXHJcbmV4cG9ydCB0eXBlIFR5cGVTdGF0dXNMYWJlbCA9XHJcbiAgfCAnU3RhbmRhcmQnXHJcbiAgfCAnU3VjY2VzcydcclxuICB8ICdIb3QnXHJcbiAgfCAnV2FybmluZydcclxuICB8ICdEaXNhYmxlZCdcclxuICB8ICdSSEJQcmVtaWVyQmFua2luZyc7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIEZOSW5wdXRBZmZpeCB7XHJcbiAgaWNvbj86IHN0cmluZztcclxuICB0ZXh0Pzogc3RyaW5nO1xyXG4gIG9uQ2xpY2s/OiAoZTogRXZlbnQpID0+IHZvaWQ7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgRk5JbnB1dFZpc2liaWxpdHlDb25kaXRpb24ge1xyXG4gIGRlcGVuZHNPbjogc3RyaW5nO1xyXG4gIHNob3dXaGVuOiBhbnk7XHJcbiAgaGlkZVdoZW4/OiBhbnk7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgRk5JbnB1dENvbW1vblByb3BzPFQgPSBhbnk+IHtcclxuICBmaWVsZFR5cGU6ICdGTklucHV0JztcclxuICBuYW1lOiBzdHJpbmc7XHJcbiAgbGFiZWw6IHN0cmluZztcclxuICBwbGFjZWhvbGRlcj86IHN0cmluZztcclxuICBjbGFzc05hbWU/OiBzdHJpbmc7XHJcbiAgcmVxdWlyZWQ/OiBib29sZWFuO1xyXG4gIHZhbHVlPzogVDtcclxuICBkaXNhYmxlZD86IGJvb2xlYW47XHJcbiAgaGlkZGVuPzogYm9vbGVhbjtcclxuICByZWFkT25seT86IGJvb2xlYW47XHJcbiAgZmxvYXRMYWJlbFZhcmlhbnQ/OiAnaW4nIHwgJ292ZXInIHwgJ29uJztcclxuICB2YWxpZGF0b3JzPzogVmFsaWRhdG9yRm5bXTtcclxuICBlcnJvcnM/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9O1xyXG4gIHJvd3M/OiBudW1iZXI7XHJcbiAgcHJlZml4PzogRk5JbnB1dEFmZml4O1xyXG4gIHN1ZmZpeD86IEZOSW5wdXRBZmZpeDtcclxuICBoYXNTdWNjZXNzQm9yZGVyPzogYm9vbGVhbjtcclxuICB2aXNpYmlsaXR5Q29uZGl0aW9uPzogRk5JbnB1dFZpc2liaWxpdHlDb25kaXRpb247XHJcbiAgaGVscGVyVGV4dD86IHN0cmluZztcclxuICBpc0FscGhhbnVtZXJpYz86IGJvb2xlYW47XHJcbiAgaGlkZU9wdGlvbmFsPzogYm9vbGVhbjtcclxuICBpc0FkZHJlc3NMaW5lPzogYm9vbGVhbjtcclxuICBjb2xvcj86IHN0cmluZztcclxuICBsYWJlbFZhcmlhbnQ/OiBUeXBlTGFiZWxWYXJpYW50O1xyXG4gIHN0YXR1c0xhYmVsPzogVHlwZVN0YXR1c0xhYmVsO1xyXG4gIGxhYmVsU2l6ZT86IHN0cmluZztcclxuICB2YWx1ZUNvbG9yPzogc3RyaW5nO1xyXG4gIHZhbHVlU2l6ZT86IHN0cmluZztcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBGTlRleHRJbnB1dFByb3BzPFQgPSBhbnk+IGV4dGVuZHMgRk5JbnB1dENvbW1vblByb3BzPFQ+IHtcclxuICB0eXBlOiAndGV4dCcgfCAnZW1haWwnIHwgJ3RleHRhcmVhJyB8ICdoaWRkZW4nO1xyXG4gIGNvbHM/OiBudW1iZXI7XHJcbiAgbWF4TGVuZ3RoPzogbnVtYmVyO1xyXG4gIGljb24/OiB7XHJcbiAgICBuYW1lOiBzdHJpbmc7XHJcbiAgICB2YXJpYW50OiBUeXBlSWNvblZhcmlhbnQ7XHJcbiAgICBzaXplOiBUeXBlSWNvblNpemU7XHJcbiAgfTtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBGTlBhc3N3b3JkUHJvcHMgZXh0ZW5kcyBGTklucHV0Q29tbW9uUHJvcHM8c3RyaW5nPiB7XHJcbiAgdHlwZTogJ3Bhc3N3b3JkJztcclxuICB0b2dnbGVNYXNrPzogYm9vbGVhbjtcclxuICBmZWVkYmFjaz86IGJvb2xlYW47XHJcbiAgd2Vha0xhYmVsPzogc3RyaW5nO1xyXG4gIG1lZGl1bUxhYmVsPzogc3RyaW5nO1xyXG4gIHN0cm9uZ0xhYmVsPzogc3RyaW5nO1xyXG4gIGlzQ29weVRleHQ/OiBib29sZWFuO1xyXG4gIGhhc0dlbmVyYXRlS2V5PzogYm9vbGVhbjtcclxuICBvbkdlbmVyYXRlS2V5PzogKCkgPT4gdm9pZDtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBGTklucHV0TnVtYmVyUHJvcHMgZXh0ZW5kcyBGTklucHV0Q29tbW9uUHJvcHM8bnVtYmVyPiB7XHJcbiAgdHlwZTogJ251bWJlcic7XHJcbiAgbWluPzogbnVtYmVyO1xyXG4gIG1heD86IG51bWJlcjtcclxuICBzdGVwPzogbnVtYmVyO1xyXG4gIG1pbkZyYWN0aW9uRGlnaXRzPzogbnVtYmVyO1xyXG4gIG1heEZyYWN0aW9uRGlnaXRzPzogbnVtYmVyO1xyXG4gIGN1cnJlbmN5Pzogc3RyaW5nO1xyXG4gIGN1cnJlbmN5RGlzcGxheT86ICdzeW1ib2wnIHwgJ2NvZGUnIHwgJ25hbWUnO1xyXG4gIGxvY2FsZT86IHN0cmluZztcclxuICB1c2VHcm91cGluZz86IGJvb2xlYW47XHJcbiAgbW9kZT86ICdkZWNpbWFsJyB8ICdjdXJyZW5jeSc7XHJcbiAgc2hvd0J1dHRvbnM/OiBib29sZWFuO1xyXG4gIGJ1dHRvbkxheW91dD86ICdzdGFja2VkJyB8ICdob3Jpem9udGFsJyB8ICd2ZXJ0aWNhbCc7XHJcbiAgaW5jcmVtZW50QnV0dG9uSWNvbj86IHN0cmluZztcclxuICBkZWNyZW1lbnRCdXR0b25JY29uPzogc3RyaW5nO1xyXG4gIGlzQ3VycmVuY3k/OiBib29sZWFuO1xyXG4gIG1heEludGVnZXJEaWdpdHM/OiBudW1iZXI7XHJcbn1cclxuXHJcbmV4cG9ydCB0eXBlIEZOSW5wdXRCYXNlID0gRk5UZXh0SW5wdXRQcm9wcyB8IEZOUGFzc3dvcmRQcm9wcyB8IEZOSW5wdXROdW1iZXJQcm9wcztcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgRk5JbnB1dEhlbHBlciB7XHJcbiAgc2hvd0Zvcm1GaWVsZE1lc3NhZ2U6IChjb250cm9sOiBhbnksIGhlbHBlclRleHQ6IHN0cmluZykgPT4gYm9vbGVhbjtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBGTklucHV0VG9hc3Qge1xyXG4gIHN1Y2Nlc3M6IChtZXNzYWdlOiBzdHJpbmcsIHRpdGxlPzogc3RyaW5nLCBkdXJhdGlvbj86IG51bWJlcikgPT4gc3RyaW5nO1xyXG4gIGVycm9yOiAobWVzc2FnZTogc3RyaW5nLCB0aXRsZT86IHN0cmluZywgZHVyYXRpb24/OiBudW1iZXIpID0+IHN0cmluZztcclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IERFRkFVTFRfQ1VSUkVOQ1lfTUVUQSA9IFtcclxuICB7IGNvZGU6ICdVU0QnLCBsb2NhbGU6ICdlbi1VUycsIHN5bWJvbDogJyQnLCBkaWdpdDogJzEuMi0yJyB9LFxyXG4gIHsgY29kZTogJ01ZUicsIGxvY2FsZTogJ2VuLU1ZJywgc3ltYm9sOiAnUk0nLCBkaWdpdDogJzEuMi0yJyB9LFxyXG4gIHsgY29kZTogJ0VVUicsIGxvY2FsZTogJ2VuLVVTJywgc3ltYm9sOiAn4oKsJywgZGlnaXQ6ICcxLjItMicgfSxcclxuICB7IGNvZGU6ICdHQlAnLCBsb2NhbGU6ICdlbi1VUycsIHN5bWJvbDogJ8KjJywgZGlnaXQ6ICcxLjItMicgfSxcclxuICB7IGNvZGU6ICdKUFknLCBsb2NhbGU6ICdqYS1KUCcsIHN5bWJvbDogJ8KlJywgZGlnaXQ6ICcxLjAtMCcgfSxcclxuICB7IGNvZGU6ICdDTlknLCBsb2NhbGU6ICd6aC1DTicsIHN5bWJvbDogJ8KlJywgZGlnaXQ6ICcxLjItMicgfSxcclxuICB7IGNvZGU6ICdJTlInLCBsb2NhbGU6ICdlbi1JTicsIHN5bWJvbDogJ+KCuScsIGRpZ2l0OiAnMS4yLTInIH0sXHJcbl07XHJcbiJdfQ==
12
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm4taW5wdXQudHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9mbi1pbnB1dC9zcmMvbGliL2ZuLWlucHV0LnR5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxlQUFlLENBQUM7QUE0Si9DLE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUFHLElBQUksY0FBYyxDQUFlLGtCQUFrQixDQUFDLENBQUM7QUFFckYsTUFBTSxDQUFDLE1BQU0scUJBQXFCLEdBQUc7SUFDbkMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFO0lBQzdELEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRTtJQUM5RCxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUU7SUFDN0QsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFO0lBQzdELEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRTtJQUM3RCxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUU7SUFDN0QsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFO0NBQzlELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3Rpb25Ub2tlbiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBWYWxpZGF0b3JGbiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xyXG5cclxuZXhwb3J0IHR5cGUgVHlwZUljb25WYXJpYW50ID0gJ0NvbG91cicgfCAnRHVvdG9uZScgfCAnRmlsbCcgfCAnTGluZSc7XHJcbmV4cG9ydCB0eXBlIFR5cGVJY29uU2l6ZSA9IDEwIHwgMTYgfCAyMCB8IDI0IHwgMzIgfCA0ODtcclxuXHJcbmV4cG9ydCB0eXBlIFR5cGVMYWJlbFZhcmlhbnQgPVxyXG4gIHwgJ2gxJ1xyXG4gIHwgJ2gxQm9sZCdcclxuICB8ICdoMidcclxuICB8ICdoMkJvbGQnXHJcbiAgfCAnaDMnXHJcbiAgfCAnaDNCb2xkJ1xyXG4gIHwgJ3AxJ1xyXG4gIHwgJ3AxQm9sZCdcclxuICB8ICdwMidcclxuICB8ICdwMkJvbGQnXHJcbiAgfCAncDMnXHJcbiAgfCAncDNCb2xkJ1xyXG4gIHwgJ3A0J1xyXG4gIHwgJ3A0Qm9sZCdcclxuICB8ICdpbnRlcmFjdGlvbkxhcmdlJ1xyXG4gIHwgJ2ludGVyYWN0aW9uTGFyZ2VCb2xkJ1xyXG4gIHwgJ2ludGVyYWN0aW9uTWVkaXVtJ1xyXG4gIHwgJ2ludGVyYWN0aW9uTWVkaXVtQm9sZCdcclxuICB8ICdpbnRlcmFjdGlvblNtYWxsJ1xyXG4gIHwgJ2ludGVyYWN0aW9uU21hbGxCb2xkJ1xyXG4gIHwgJ2F2YXRhckxhYmVsJztcclxuXHJcbmV4cG9ydCB0eXBlIFR5cGVTdGF0dXNMYWJlbCA9XHJcbiAgfCAnU3RhbmRhcmQnXHJcbiAgfCAnU3VjY2VzcydcclxuICB8ICdIb3QnXHJcbiAgfCAnV2FybmluZydcclxuICB8ICdEaXNhYmxlZCdcclxuICB8ICdSSEJQcmVtaWVyQmFua2luZyc7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIEZOSW5wdXRBZmZpeCB7XHJcbiAgaWNvbj86IHN0cmluZztcclxuICB0ZXh0Pzogc3RyaW5nO1xyXG4gIG9uQ2xpY2s/OiAoZTogRXZlbnQpID0+IHZvaWQ7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgRk5JbnB1dFZpc2liaWxpdHlDb25kaXRpb24ge1xyXG4gIGRlcGVuZHNPbjogc3RyaW5nO1xyXG4gIHNob3dXaGVuOiBhbnk7XHJcbiAgaGlkZVdoZW4/OiBhbnk7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgRk5JbnB1dENvbW1vblByb3BzPFQgPSBhbnk+IHtcclxuICBmaWVsZFR5cGU6ICdGTklucHV0JztcclxuICBuYW1lOiBzdHJpbmc7XHJcbiAgbGFiZWw6IHN0cmluZztcclxuICBwbGFjZWhvbGRlcj86IHN0cmluZztcclxuICBjbGFzc05hbWU/OiBzdHJpbmc7XHJcbiAgcmVxdWlyZWQ/OiBib29sZWFuO1xyXG4gIHZhbHVlPzogVDtcclxuICBkaXNhYmxlZD86IGJvb2xlYW47XHJcbiAgaGlkZGVuPzogYm9vbGVhbjtcclxuICByZWFkT25seT86IGJvb2xlYW47XHJcbiAgZmxvYXRMYWJlbFZhcmlhbnQ/OiAnaW4nIHwgJ292ZXInIHwgJ29uJztcclxuICB2YWxpZGF0b3JzPzogVmFsaWRhdG9yRm5bXTtcclxuICBlcnJvcnM/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9O1xyXG4gIHJvd3M/OiBudW1iZXI7XHJcbiAgcHJlZml4PzogRk5JbnB1dEFmZml4O1xyXG4gIHN1ZmZpeD86IEZOSW5wdXRBZmZpeDtcclxuICBoYXNTdWNjZXNzQm9yZGVyPzogYm9vbGVhbjtcclxuICB2aXNpYmlsaXR5Q29uZGl0aW9uPzogRk5JbnB1dFZpc2liaWxpdHlDb25kaXRpb247XHJcbiAgaGVscGVyVGV4dD86IHN0cmluZztcclxuICBpc0FscGhhbnVtZXJpYz86IGJvb2xlYW47XHJcbiAgaGlkZU9wdGlvbmFsPzogYm9vbGVhbjtcclxuICBpc0FkZHJlc3NMaW5lPzogYm9vbGVhbjtcclxuICBjb2xvcj86IHN0cmluZztcclxuICBsYWJlbFZhcmlhbnQ/OiBUeXBlTGFiZWxWYXJpYW50O1xyXG4gIHN0YXR1c0xhYmVsPzogVHlwZVN0YXR1c0xhYmVsO1xyXG4gIGxhYmVsU2l6ZT86IHN0cmluZztcclxuICB2YWx1ZUNvbG9yPzogc3RyaW5nO1xyXG4gIHZhbHVlU2l6ZT86IHN0cmluZztcclxuICBpc0NvcHlUZXh0PzogYm9vbGVhbjtcclxuICBoYXNHZW5lcmF0ZUtleT86IGJvb2xlYW47XHJcbiAgb25HZW5lcmF0ZUtleT86ICgpID0+IHZvaWQ7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgRk5UZXh0SW5wdXRQcm9wczxUID0gYW55PiBleHRlbmRzIEZOSW5wdXRDb21tb25Qcm9wczxUPiB7XHJcbiAgdHlwZTogJ3RleHQnIHwgJ2VtYWlsJyB8ICd0ZXh0YXJlYScgfCAnaGlkZGVuJztcclxuICBjb2xzPzogbnVtYmVyO1xyXG4gIG1heExlbmd0aD86IG51bWJlcjtcclxuICBpY29uPzoge1xyXG4gICAgbmFtZTogc3RyaW5nO1xyXG4gICAgdmFyaWFudDogVHlwZUljb25WYXJpYW50O1xyXG4gICAgc2l6ZTogVHlwZUljb25TaXplO1xyXG4gIH07XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgRk5QYXNzd29yZFByb3BzIGV4dGVuZHMgRk5JbnB1dENvbW1vblByb3BzPHN0cmluZz4ge1xyXG4gIHR5cGU6ICdwYXNzd29yZCc7XHJcbiAgdG9nZ2xlTWFzaz86IGJvb2xlYW47XHJcbiAgZmVlZGJhY2s/OiBib29sZWFuO1xyXG4gIHdlYWtMYWJlbD86IHN0cmluZztcclxuICBtZWRpdW1MYWJlbD86IHN0cmluZztcclxuICBzdHJvbmdMYWJlbD86IHN0cmluZztcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBGTklucHV0TnVtYmVyUHJvcHMgZXh0ZW5kcyBGTklucHV0Q29tbW9uUHJvcHM8bnVtYmVyPiB7XHJcbiAgdHlwZTogJ251bWJlcic7XHJcbiAgbWluPzogbnVtYmVyO1xyXG4gIG1heD86IG51bWJlcjtcclxuICBzdGVwPzogbnVtYmVyO1xyXG4gIG1pbkZyYWN0aW9uRGlnaXRzPzogbnVtYmVyO1xyXG4gIG1heEZyYWN0aW9uRGlnaXRzPzogbnVtYmVyO1xyXG4gIGN1cnJlbmN5Pzogc3RyaW5nO1xyXG4gIGN1cnJlbmN5RGlzcGxheT86ICdzeW1ib2wnIHwgJ2NvZGUnIHwgJ25hbWUnO1xyXG4gIGxvY2FsZT86IHN0cmluZztcclxuICB1c2VHcm91cGluZz86IGJvb2xlYW47XHJcbiAgbW9kZT86ICdkZWNpbWFsJyB8ICdjdXJyZW5jeSc7XHJcbiAgc2hvd0J1dHRvbnM/OiBib29sZWFuO1xyXG4gIGJ1dHRvbkxheW91dD86ICdzdGFja2VkJyB8ICdob3Jpem9udGFsJyB8ICd2ZXJ0aWNhbCc7XHJcbiAgaW5jcmVtZW50QnV0dG9uSWNvbj86IHN0cmluZztcclxuICBkZWNyZW1lbnRCdXR0b25JY29uPzogc3RyaW5nO1xyXG4gIGlzQ3VycmVuY3k/OiBib29sZWFuO1xyXG4gIG1heEludGVnZXJEaWdpdHM/OiBudW1iZXI7XHJcbn1cclxuXHJcbmV4cG9ydCB0eXBlIEZOSW5wdXRCYXNlID0gRk5UZXh0SW5wdXRQcm9wcyB8IEZOUGFzc3dvcmRQcm9wcyB8IEZOSW5wdXROdW1iZXJQcm9wcztcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgRk5JbnB1dEhlbHBlciB7XHJcbiAgc2hvd0Zvcm1GaWVsZE1lc3NhZ2U6IChjb250cm9sOiBhbnksIGhlbHBlclRleHQ6IHN0cmluZykgPT4gYm9vbGVhbjtcclxuICB0cmFuc2xhdGU6IChrZXk6IHN0cmluZykgPT4gc3RyaW5nO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFRvYXN0IHtcclxuICBpZDogc3RyaW5nO1xyXG4gIHR5cGU6ICdzdWNjZXNzJyB8ICd3YXJuJyB8ICdlcnJvcicgfCAnaW5mbyc7XHJcbiAgbWVzc2FnZTogc3RyaW5nO1xyXG4gIGlzVmlzaWJsZTogYm9vbGVhbjtcclxuICBwb3NpdGlvbj86ICd0b3AnIHwgJ2JvdHRvbSc7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgRk5JbnB1dFRvYXN0IHtcclxuICB0b2FzdHMkOiBPYnNlcnZhYmxlPFRvYXN0W10+O1xyXG4gIHN1Y2Nlc3M6IChcclxuICAgIG1lc3NhZ2U6IHN0cmluZyxcclxuICAgIHRpdGxlPzogc3RyaW5nLFxyXG4gICAgZHVyYXRpb24/OiBudW1iZXIsXHJcbiAgICBwb3NpdGlvbj86ICd0b3AnIHwgJ2JvdHRvbScsXHJcbiAgKSA9PiBzdHJpbmc7XHJcbiAgZXJyb3I6IChcclxuICAgIG1lc3NhZ2U6IHN0cmluZyxcclxuICAgIHRpdGxlPzogc3RyaW5nLFxyXG4gICAgZHVyYXRpb24/OiBudW1iZXIsXHJcbiAgICBwb3NpdGlvbj86ICd0b3AnIHwgJ2JvdHRvbScsXHJcbiAgKSA9PiBzdHJpbmc7XHJcbiAgcmVtb3ZlOiAoaWQ6IHN0cmluZykgPT4gdm9pZDtcclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IEZOX1RPQVNUX1NFUlZJQ0UgPSBuZXcgSW5qZWN0aW9uVG9rZW48Rk5JbnB1dFRvYXN0PignRk5fVE9BU1RfU0VSVklDRScpO1xyXG5cclxuZXhwb3J0IGNvbnN0IERFRkFVTFRfQ1VSUkVOQ1lfTUVUQSA9IFtcclxuICB7IGNvZGU6ICdVU0QnLCBsb2NhbGU6ICdlbi1VUycsIHN5bWJvbDogJyQnLCBkaWdpdDogJzEuMi0yJyB9LFxyXG4gIHsgY29kZTogJ01ZUicsIGxvY2FsZTogJ2VuLU1ZJywgc3ltYm9sOiAnUk0nLCBkaWdpdDogJzEuMi0yJyB9LFxyXG4gIHsgY29kZTogJ0VVUicsIGxvY2FsZTogJ2VuLVVTJywgc3ltYm9sOiAn4oKsJywgZGlnaXQ6ICcxLjItMicgfSxcclxuICB7IGNvZGU6ICdHQlAnLCBsb2NhbGU6ICdlbi1VUycsIHN5bWJvbDogJ8KjJywgZGlnaXQ6ICcxLjItMicgfSxcclxuICB7IGNvZGU6ICdKUFknLCBsb2NhbGU6ICdqYS1KUCcsIHN5bWJvbDogJ8KlJywgZGlnaXQ6ICcxLjAtMCcgfSxcclxuICB7IGNvZGU6ICdDTlknLCBsb2NhbGU6ICd6aC1DTicsIHN5bWJvbDogJ8KlJywgZGlnaXQ6ICcxLjItMicgfSxcclxuICB7IGNvZGU6ICdJTlInLCBsb2NhbGU6ICdlbi1JTicsIHN5bWJvbDogJ+KCuScsIGRpZ2l0OiAnMS4yLTInIH0sXHJcbl07XHJcbiJdfQ==
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { EventEmitter, inject, signal, ViewChildren, ViewChild, Output, Input, ChangeDetectionStrategy, Component } from '@angular/core';
2
+ import { InjectionToken, inject, EventEmitter, signal, ViewChildren, ViewChild, Output, Input, ChangeDetectionStrategy, Component } from '@angular/core';
3
3
  import * as i2 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
5
  import * as i1 from '@angular/forms';
@@ -9,6 +9,7 @@ import { TranslateService, TranslateModule } from '@ngx-translate/core';
9
9
  import { Subscription, merge } from 'rxjs';
10
10
  import { startWith } from 'rxjs/operators';
11
11
 
12
+ const FN_TOAST_SERVICE = new InjectionToken('FN_TOAST_SERVICE');
12
13
  const DEFAULT_CURRENCY_META = [
13
14
  { code: 'USD', locale: 'en-US', symbol: '$', digit: '1.2-2' },
14
15
  { code: 'MYR', locale: 'en-MY', symbol: 'RM', digit: '1.2-2' },
@@ -20,28 +21,36 @@ const DEFAULT_CURRENCY_META = [
20
21
  ];
21
22
 
22
23
  const CORE_ICONS = {
23
- 'eye-open': `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><circle cx="12" cy="12" r="3" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>`,
24
- 'eye-close': `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><line x1="1" y1="1" x2="23" y2="23" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>`,
25
- 'two-square': `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="9" y="9" width="13" height="13" rx="2" ry="2" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>`,
26
- 'round-arrow-top-left': `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12 2a10 10 0 1 0 10 10A10 10 0 0 0 12 2zm0 18a8 8 0 1 1 8-8 8 8 0 0 1-8 8z" fill="currentColor"/><path d="M15 9H9v6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M9 9l6 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>`,
27
- 'check-circle': `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M22 4L12 14.01l-3-3" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>`,
24
+ 'eye-open': `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M2 12s4-8 10-8 10 8 10 8-4 8-10 8-10-8-10-8z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><circle cx="12" cy="12" r="3" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>`,
25
+ 'eye-close': `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M2 10a11 11 0 0 0 20 0" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M5 13l-1 2M12 14v2M19 13l1 2" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>`,
26
+ 'two-square': `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="8" y="4" width="12" height="12" rx="2" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M4 8v10a2 2 0 0 0 2 2h10" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>`,
27
+ 'round-arrow-top-left': `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M23 4v6h-6M1 20v-6h6M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>`,
28
+ 'check-circle': `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2"/><path d="M8 12l3 3 5-5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>`,
28
29
  'info-circle': `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><line x1="12" y1="16" x2="12" y2="12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><line x1="12" y1="8" x2="12.01" y2="8" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>`,
29
30
  'alert-circle': `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><line x1="12" y1="8" x2="12" y2="12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><line x1="12" y1="16" x2="12.01" y2="16" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>`,
31
+ 'exclamation-circle': `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><line x1="12" y1="8" x2="12" y2="12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><line x1="12" y1="16" x2="12.01" y2="16" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>`,
32
+ cross: `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M18 6L6 18M6 6l12 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>`,
30
33
  };
31
34
  class FNInput {
32
35
  cdr;
33
36
  field = {};
34
37
  helperHandle;
35
38
  toastService;
39
+ injectedToastService = inject(FN_TOAST_SERVICE, { optional: true });
40
+ get effectiveToastService() {
41
+ return this.toastService || this.injectedToastService || undefined;
42
+ }
36
43
  currencyMeta = DEFAULT_CURRENCY_META;
37
44
  defaultLocale = 'en-US';
38
45
  form;
39
46
  valueChange = new EventEmitter();
40
47
  fieldBlur = new EventEmitter();
41
- translate = inject(TranslateService);
48
+ translateService = inject(TranslateService);
42
49
  hasFocus = signal(false);
43
50
  textareaElement;
44
51
  iconContainers;
52
+ // Internal Toast State
53
+ toasts = signal([]);
45
54
  // Removed HttpClient injection
46
55
  subs = new Subscription();
47
56
  sizeMap = {
@@ -97,6 +106,7 @@ class FNInput {
97
106
  this.control.setValue(this.field.value);
98
107
  this.setupVisibilityCondition();
99
108
  this.setupFieldMessageListener();
109
+ this.setupToastSubscription();
100
110
  }
101
111
  ngOnDestroy() {
102
112
  this.subs.unsubscribe();
@@ -131,6 +141,12 @@ class FNInput {
131
141
  if (this.field.type === 'number' && this.field.isCurrency && this.control?.value) {
132
142
  this.formatInitialCurrencyValue();
133
143
  }
144
+ this.setupIconContainersListener();
145
+ }
146
+ setupIconContainersListener() {
147
+ this.subs.add(this.iconContainers.changes.subscribe(() => {
148
+ this.updateAllIcons();
149
+ }));
134
150
  }
135
151
  enforceLowercase(event) {
136
152
  const input = event.target;
@@ -307,6 +323,10 @@ class FNInput {
307
323
  }
308
324
  this.control.markAsTouched();
309
325
  }
326
+ togglePasswordVisibility() {
327
+ this.showPassword = !this.showPassword;
328
+ this.updateAllIcons();
329
+ }
310
330
  handleInput(event) {
311
331
  const target = event.target;
312
332
  const cursorPosition = target.selectionStart;
@@ -875,8 +895,10 @@ class FNInput {
875
895
  if (!this.control.value)
876
896
  return;
877
897
  navigator.clipboard.writeText(this.control.value).then(() => {
878
- if (this.toastService) {
879
- this.toastService.success('Copied to clipboard', 'Success', 1000);
898
+ const service = this.effectiveToastService;
899
+ if (service) {
900
+ // Position set to top as requested
901
+ service.success('Copied to clipboard', 'Success', 2000);
880
902
  }
881
903
  });
882
904
  }
@@ -936,6 +958,38 @@ class FNInput {
936
958
  }
937
959
  this.cdr.detectChanges();
938
960
  }
961
+ setupToastSubscription() {
962
+ const service = this.effectiveToastService;
963
+ if (service) {
964
+ this.subs.add(service.toasts$.subscribe((toasts) => {
965
+ this.toasts.set(toasts);
966
+ // Wait for DOM to update then render toast icons
967
+ this.updateAllIcons();
968
+ }));
969
+ }
970
+ }
971
+ removeToast(id) {
972
+ this.effectiveToastService?.remove(id);
973
+ }
974
+ getTranslatedMessage(message) {
975
+ if (this.helperHandle && typeof this.helperHandle.translate === 'function') {
976
+ return this.helperHandle.translate(message);
977
+ }
978
+ return message;
979
+ }
980
+ getToastIconName(toast) {
981
+ switch (toast.type) {
982
+ case 'success':
983
+ return 'check-circle';
984
+ case 'warn':
985
+ case 'info':
986
+ return 'info-circle';
987
+ case 'error':
988
+ return 'exclamation-circle';
989
+ default:
990
+ return 'info-circle';
991
+ }
992
+ }
939
993
  showFormFieldMessage(control, helperText) {
940
994
  if (this.helperHandle) {
941
995
  return this.helperHandle.showFormFieldMessage(control, helperText);
@@ -953,7 +1007,7 @@ class FNInput {
953
1007
  .split('::')
954
1008
  .map((part) => part.trim())
955
1009
  .filter((part) => !!part)
956
- .map((part) => this.translate.instant(part))
1010
+ .map((part) => this.translateService.instant(part))
957
1011
  .join(' ') + this.getEndSymbol(labelStr));
958
1012
  }
959
1013
  catch (e) {
@@ -1084,7 +1138,7 @@ class FNInput {
1084
1138
  }
1085
1139
  }
1086
1140
  return (this.field?.errors?.['default'] ||
1087
- 'Please enter ' + this.translate.instant(this.field?.label));
1141
+ 'Please enter ' + this.translateService.instant(this.field?.label));
1088
1142
  }
1089
1143
  return this.field?.helperText || '';
1090
1144
  }
@@ -1095,11 +1149,11 @@ class FNInput {
1095
1149
  return !!(this.control?.valid && this.control?.touched);
1096
1150
  }
1097
1151
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FNInput, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1098
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: FNInput, isStandalone: true, selector: "fn-input", inputs: { field: "field", helperHandle: "helperHandle", toastService: "toastService", currencyMeta: "currencyMeta", defaultLocale: "defaultLocale", form: "form" }, outputs: { valueChange: "valueChange", fieldBlur: "fieldBlur" }, viewQueries: [{ propertyName: "textareaElement", first: true, predicate: ["fnTextarea"], descendants: true }, { propertyName: "iconContainers", predicate: ["iconContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "@if (field.name && isVisible() && !field.hidden) {\r\n <div class=\"fn-input-container\">\r\n @if (field.type! !== 'hidden') {\r\n <label\r\n [for]=\"uniqueId\"\r\n class=\"fn-label\"\r\n [ngStyle]=\"{\r\n color: field.color || '#03182b',\r\n 'font-size': field.labelSize || '',\r\n }\"\r\n >\r\n {{ getTranslatedLabel(field.label) }}\r\n @if (!field.required && !field.hideOptional) {\r\n <span>&nbsp;(Optional)</span>\r\n }\r\n </label>\r\n }\r\n\r\n <ng-container>\r\n @switch (field.type) {\r\n <!-- Textarea Field -->\r\n @case ('textarea') {\r\n <textarea\r\n #fnTextarea\r\n style=\"resize: none\"\r\n [name]=\"field.name\"\r\n [id]=\"uniqueId\"\r\n [required]=\"field.required || false\"\r\n [placeholder]=\"field.placeholder || '' | translate\"\r\n [disabled]=\"field.disabled || false\"\r\n [rows]=\"field.rows || 1\"\r\n [readonly]=\"field.readOnly || false\"\r\n [formControl]=\"control\"\r\n (input)=\"handleTextArea($event)\"\r\n (blur)=\"handleBlur($event)\"\r\n class=\"fn-input-field\"\r\n [ngClass]=\"{\r\n disabled: control.disabled || field.readOnly,\r\n error: control.touched && control.errors,\r\n success: field['hasSuccessBorder'] && control.valid && !control.errors,\r\n }\"\r\n [ngStyle]=\"{\r\n color: field.valueColor || 'inherit',\r\n 'font-size': field.valueSize || '',\r\n }\"\r\n (focus)=\"onFocus()\"\r\n ></textarea>\r\n }\r\n\r\n <!-- Password Field -->\r\n @case ('password') {\r\n <div class=\"relative w-full\">\r\n @if (field.prefix?.icon) {\r\n <div class=\"absolute left-0 top-1/2 -translate-y-1/2 pl-3 flex items-center\">\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"field.prefix!.icon\"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"medium\"\r\n [attr.data-icon-color]=\"control.disabled ? '#c4cdd2' : '#03182b'\"\r\n ></div>\r\n </div>\r\n }\r\n <input\r\n [type]=\"showPassword ? 'text' : 'password'\"\r\n [id]=\"uniqueId\"\r\n [required]=\"field.required || false\"\r\n [disabled]=\"field.disabled || false\"\r\n [formControl]=\"control\"\r\n [placeholder]=\"field.placeholder || '' | translate\"\r\n [readonly]=\"field.readOnly || false\"\r\n (input)=\"isAlphanumeric ? handleAlphanumericInput($event) : handleInput($event)\"\r\n (focus)=\"onPasswordFocus()\"\r\n (blur)=\"handlePasswordBlur($event)\"\r\n class=\"fn-input-field overflow-hidden text-ellipsis\"\r\n [ngClass]=\"{\r\n disabled: control.disabled || field.readOnly,\r\n error: control.touched && control.errors,\r\n success: field['hasSuccessBorder'] && control.valid,\r\n 'pl-10': field.prefix?.icon,\r\n 'pr-12':\r\n (field.toggleMask && !field.isCopyText) ||\r\n (!field.toggleMask && field.isCopyText),\r\n 'pr-24': field.toggleMask && field.isCopyText,\r\n 'pr-32': field.toggleMask && field.isCopyText && field.hasGenerateKey,\r\n }\"\r\n [ngStyle]=\"{\r\n color: field.valueColor || 'inherit',\r\n 'font-size': field.valueSize || '',\r\n }\"\r\n />\r\n\r\n <div class=\"absolute right-0 top-1/2 -translate-y-1/2 flex items-center pr-3 gap-2\">\r\n @if (field.toggleMask && !field.isCopyText) {\r\n <span\r\n class=\"cursor-pointer\"\r\n (click)=\"showPassword = !showPassword\"\r\n (keydown)=\"showPassword = !showPassword\"\r\n >\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"showPassword ? 'eye-open' : 'eye-close'\"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"large\"\r\n data-icon-color=\"#03182b\"\r\n ></div>\r\n </span>\r\n } @else if (field.isCopyText && !field.toggleMask) {\r\n <span\r\n class=\"cursor-pointer\"\r\n (click)=\"copyText($event)\"\r\n (keydown)=\"copyText($event)\"\r\n >\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n data-icon-name=\"two-square\"\r\n data-icon-color=\"#03182b\"\r\n ></div>\r\n </span>\r\n @if (field.hasGenerateKey) {\r\n <span\r\n class=\"cursor-pointer\"\r\n (click)=\"field.onGenerateKey && field.onGenerateKey()\"\r\n (keydown)=\"field.onGenerateKey && field.onGenerateKey()\"\r\n >\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n data-icon-name=\"two-square\"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"large\"\r\n data-icon-color=\"#03182b\"\r\n ></div>\r\n </span>\r\n }\r\n } @else if (field.toggleMask && field.isCopyText) {\r\n <span\r\n class=\"cursor-pointer\"\r\n (click)=\"showPassword = !showPassword\"\r\n (keydown)=\"showPassword = !showPassword\"\r\n >\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"showPassword ? 'eye-open' : 'eye-close'\"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"large\"\r\n data-icon-color=\"#03182b\"\r\n ></div>\r\n </span>\r\n <span\r\n class=\"cursor-pointer\"\r\n (click)=\"copyText($event)\"\r\n (keydown)=\"copyText($event)\"\r\n >\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n data-icon-name=\"two-square\"\r\n data-icon-color=\"#03182b\"\r\n ></div>\r\n </span>\r\n @if (field.hasGenerateKey) {\r\n <span\r\n class=\"cursor-pointer\"\r\n (click)=\"field.onGenerateKey && field.onGenerateKey()\"\r\n (keydown)=\"field.onGenerateKey && field.onGenerateKey()\"\r\n [ngClass]=\"{ 'opacity-50 cursor-not-allowed': !control.value }\"\r\n >\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n data-icon-name=\"round-arrow-top-left\"\r\n data-icon-color=\"#03182b\"\r\n ></div>\r\n </span>\r\n }\r\n }\r\n </div>\r\n </div>\r\n\r\n @if (field.feedback && isPasswordFocused) {\r\n <div class=\"mt-2 space-y-1\">\r\n <div class=\"flex items-center justify-between text-xs\">\r\n <span class=\"font-medium\" [ngClass]=\"strengthClass\">\r\n {{ passwordStrengthLabel | translate }}\r\n </span>\r\n <div class=\"flex items-center gap-1\">\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"\r\n passwordStrengthPercent > 50 ? 'check-circle' : 'info-circle'\r\n \"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"extrasmall\"\r\n [attr.data-icon-color]=\"\r\n passwordStrengthPercent <= 25\r\n ? '#ef3e42'\r\n : passwordStrengthPercent <= 75\r\n ? '#ff9f00'\r\n : '#6cc24a'\r\n \"\r\n ></div>\r\n </div>\r\n </div>\r\n <div class=\"h-1.5 w-full bg-[#eef0f2] rounded-full overflow-hidden\">\r\n <div\r\n class=\"h-full transition-all duration-300 rounded-full\"\r\n [ngClass]=\"{\r\n 'bg-[#ef3e42]': passwordStrengthPercent <= 25,\r\n 'bg-[#ff9f00]': passwordStrengthPercent > 25 && passwordStrengthPercent <= 75,\r\n 'bg-[#6cc24a]': passwordStrengthPercent > 75,\r\n }\"\r\n [style.width.%]=\"passwordStrengthPercent\"\r\n ></div>\r\n </div>\r\n </div>\r\n }\r\n }\r\n\r\n <!-- Number Field -->\r\n @case ('number') {\r\n <div class=\"relative w-full\">\r\n @if (field.prefix?.icon) {\r\n <div class=\"absolute left-0 top-1/2 -translate-y-1/2 pl-3 flex items-center\">\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"field.prefix!.icon\"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"medium\"\r\n [attr.data-icon-color]=\"control.disabled ? '#c4cdd2' : '#03182b'\"\r\n ></div>\r\n </div>\r\n }\r\n <input\r\n [type]=\"field.type === 'number' && field.isCurrency ? 'text' : 'number'\"\r\n [name]=\"field.name\"\r\n [id]=\"uniqueId\"\r\n [required]=\"field.required || false\"\r\n [placeholder]=\"field.placeholder || '' | translate\"\r\n [disabled]=\"isDisabled || false\"\r\n [readOnly]=\"field.readOnly || false\"\r\n [formControl]=\"control\"\r\n [min]=\"field.type === 'number' && !field.isCurrency ? 0 : null\"\r\n [max]=\"field.type === 'number' && !field.isCurrency ? field.max : null\"\r\n [step]=\"field.type === 'number' && !field.isCurrency ? field.step || 1 : null\"\r\n (input)=\"handleNumberInput($event, field.minFractionDigits || 2)\"\r\n (paste)=\"handleNumberPaste($event, field.minFractionDigits || 2)\"\r\n (blur)=\"handleBlur($event, field.minFractionDigits || 2)\"\r\n (keydown)=\"handleNumberKeydown($event, field.isCurrency || false)\"\r\n class=\"fn-input-field\"\r\n [ngClass]=\"{\r\n disabled: control.disabled || field.readOnly,\r\n error: control.touched && control.errors,\r\n success: field['hasSuccessBorder'] && control.valid && !control.errors,\r\n 'pl-10': field.prefix?.icon,\r\n 'text-[24px] font-bold': field.isCurrency,\r\n }\"\r\n [ngStyle]=\"{\r\n color: field.valueColor || 'inherit',\r\n 'font-size': field.valueSize || '',\r\n }\"\r\n (focus)=\"onFocus()\"\r\n />\r\n </div>\r\n }\r\n\r\n <!-- Default Input Field (text, email, etc.) -->\r\n @default {\r\n <div class=\"relative z-0\">\r\n @if (field.prefix?.icon) {\r\n <div class=\"absolute left-0 top-1/2 -translate-y-1/2 pl-3 flex items-center\">\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"field.prefix!.icon\"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"medium\"\r\n [attr.data-icon-color]=\"control.disabled ? '#c4cdd2' : '#03182b'\"\r\n ></div>\r\n </div>\r\n }\r\n <input\r\n [type]=\"field.type\"\r\n [name]=\"field.name\"\r\n [id]=\"uniqueId\"\r\n [required]=\"field.required || false\"\r\n [placeholder]=\"field.placeholder || '' | translate\"\r\n [disabled]=\"field.disabled || false\"\r\n [readOnly]=\"field.readOnly || false\"\r\n [formControl]=\"control\"\r\n (input)=\"\r\n isEmailField\r\n ? handleEmailInput($event)\r\n : field.type === 'text' && isAlphanumeric\r\n ? handleAlphanumericInput($event)\r\n : handleInput($event)\r\n \"\r\n (blur)=\"handleBlur($event)\"\r\n class=\"fn-input-field\"\r\n [ngClass]=\"{\r\n disabled: control.disabled || field.readOnly,\r\n error: control.touched && control.errors,\r\n success: field['hasSuccessBorder'] && control.valid && !control.errors,\r\n 'pl-10': field.prefix?.icon,\r\n 'pr-10': field.icon || field.suffix?.icon,\r\n }\"\r\n [ngStyle]=\"{\r\n color: field.valueColor || 'inherit',\r\n 'font-size': field.valueSize || '',\r\n }\"\r\n (focus)=\"onFocus()\"\r\n />\r\n @if (field.icon || field.suffix?.icon) {\r\n <span class=\"absolute right-0 top-1/2 -translate-y-1/2 pr-3 flex items-center\">\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"field.suffix?.icon || field.icon!.name\"\r\n [attr.data-icon-variant]=\"field.icon?.variant || 'Line'\"\r\n [attr.data-icon-size]=\"field.icon ? getIconSizeName(field.icon.size) : 'medium'\"\r\n [attr.data-icon-color]=\"control.disabled ? '#c4cdd2' : '#03182b'\"\r\n ></div>\r\n </span>\r\n }\r\n </div>\r\n }\r\n }\r\n </ng-container>\r\n\r\n @if (showFormFieldMessage(control, helperText)) {\r\n <div class=\"fn-field-message-container\">\r\n <span\r\n class=\"fn-field-message-text\"\r\n [ngClass]=\"{\r\n error: isError,\r\n success: isSuccess,\r\n }\"\r\n >\r\n {{ getFieldMessage() | translate }}\r\n </span>\r\n </div>\r\n }\r\n </div>\r\n}\r\n", styles: [".fn-input-container{display:flex;flex-direction:column;gap:8px;width:100%}.fn-label{color:#03182b;font-family:inherit;font-size:14px;font-weight:500;line-height:20px;margin-bottom:4px}.fn-input-field{background-color:#eff9fd;border:0!important;border-bottom:1px solid #c4cdd2!important;padding:8px 12px;width:100%;box-sizing:border-box;transition:border-color .2s ease-in-out;border-radius:0!important;appearance:none!important}.fn-input-field:focus{border-bottom:1px solid #0067b1!important;outline:none}.fn-input-field.error{border-bottom:1px solid #ef3e42!important}.fn-input-field.disabled{background-color:#eef0f2;color:#c4cdd2;cursor:not-allowed}.fn-input-field.pl-10{padding-left:36px!important}.fn-input-field.pr-10{padding-right:36px!important}.fn-input-field.pr-12{padding-right:44px!important}.fn-input-field.pr-24{padding-right:88px!important}.fn-input-field.pr-32{padding-right:120px!important}.icon-container{display:flex;align-items:center;justify-content:center;width:24px;height:24px;color:inherit}.fn-field-message-container{display:flex;align-items:center;gap:4px;margin-top:4px;min-height:20px}.fn-field-message-text{font-family:inherit;font-size:12px;font-weight:400;line-height:16px;color:#818c95}.fn-field-message-text.error{color:#ef3e42}.fn-field-message-text.success{color:#6cc24a}.mt-2{margin-top:.5rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * (1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.text-xs{font-size:.75rem;line-height:1rem}.font-medium{font-weight:500}.bg-\\[\\#eef0f2\\]{background-color:#eef0f2}.bg-\\[\\#ef3e42\\]{background-color:#ef3e42}.bg-\\[\\#ff9f00\\]{background-color:#ff9f00}.bg-\\[\\#6cc24a\\]{background-color:#6cc24a}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-300{transition-duration:.3s}.rounded-full{border-radius:9999px}.overflow-hidden{overflow:hidden}.h-1\\.5{height:.375rem}.w-full{width:100%}.flex{display:flex}.items-center{align-items:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.pl-3{padding-left:.75rem}.pr-3{padding-right:.75rem}.absolute{position:absolute}.right-0{right:0}.left-0{left:0}.top-1\\/2{top:50%}.-translate-y-1\\/2{transform:translateY(-50%)}.z-0{z-index:0}.relative{position:relative}.cursor-pointer{cursor:pointer}.text-ellipsis{text-overflow:ellipsis}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1152
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: FNInput, isStandalone: true, selector: "fn-input", inputs: { field: "field", helperHandle: "helperHandle", toastService: "toastService", currencyMeta: "currencyMeta", defaultLocale: "defaultLocale", form: "form" }, outputs: { valueChange: "valueChange", fieldBlur: "fieldBlur" }, viewQueries: [{ propertyName: "textareaElement", first: true, predicate: ["fnTextarea"], descendants: true }, { propertyName: "iconContainers", predicate: ["iconContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "@if (field.name && isVisible() && !field.hidden) {\r\n <div class=\"fn-input-container\">\r\n @if (field.type! !== 'hidden') {\r\n <label\r\n [for]=\"uniqueId\"\r\n class=\"fn-label\"\r\n [ngStyle]=\"{\r\n color: field.color || '#03182b',\r\n 'font-size': field.labelSize || '',\r\n }\"\r\n >\r\n {{ getTranslatedLabel(field.label) }}\r\n @if (!field.required && !field.hideOptional) {\r\n <span>&nbsp;(Optional)</span>\r\n }\r\n </label>\r\n }\r\n\r\n <ng-container>\r\n @switch (field.type) {\r\n <!-- Textarea Field -->\r\n @case ('textarea') {\r\n <textarea\r\n #fnTextarea\r\n style=\"resize: none\"\r\n [name]=\"field.name\"\r\n [id]=\"uniqueId\"\r\n [required]=\"field.required || false\"\r\n [placeholder]=\"field.placeholder || '' | translate\"\r\n [disabled]=\"field.disabled || false\"\r\n [rows]=\"field.rows || 1\"\r\n [readonly]=\"field.readOnly || false\"\r\n [formControl]=\"control\"\r\n (input)=\"handleTextArea($event)\"\r\n (blur)=\"handleBlur($event)\"\r\n class=\"fn-input-field\"\r\n [ngClass]=\"{\r\n disabled: control.disabled || field.readOnly,\r\n error: control.touched && control.errors,\r\n success: field['hasSuccessBorder'] && control.valid && !control.errors,\r\n }\"\r\n [ngStyle]=\"{\r\n color: field.valueColor || 'inherit',\r\n 'font-size': field.valueSize || '',\r\n }\"\r\n (focus)=\"onFocus()\"\r\n ></textarea>\r\n }\r\n\r\n <!-- Password Field -->\r\n @case ('password') {\r\n <div class=\"relative w-full\">\r\n @if (field.prefix?.icon) {\r\n <div class=\"absolute left-0 top-1/2 -translate-y-1/2 pl-3 flex items-center\">\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"field.prefix!.icon\"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"medium\"\r\n [attr.data-icon-color]=\"control.disabled ? '#c4cdd2' : '#03182b'\"\r\n ></div>\r\n </div>\r\n }\r\n <input\r\n [type]=\"showPassword ? 'text' : 'password'\"\r\n [id]=\"uniqueId\"\r\n [required]=\"field.required || false\"\r\n [disabled]=\"field.disabled || false\"\r\n [formControl]=\"control\"\r\n [placeholder]=\"field.placeholder || '' | translate\"\r\n [readonly]=\"field.readOnly || false\"\r\n (input)=\"isAlphanumeric ? handleAlphanumericInput($event) : handleInput($event)\"\r\n (focus)=\"onPasswordFocus()\"\r\n (blur)=\"handlePasswordBlur($event)\"\r\n class=\"fn-input-field overflow-hidden text-ellipsis\"\r\n [ngClass]=\"{\r\n disabled: control.disabled || field.readOnly,\r\n error: control.touched && control.errors,\r\n success: field['hasSuccessBorder'] && control.valid,\r\n 'pl-10': field.prefix?.icon,\r\n 'pr-12':\r\n (field.toggleMask && !field.isCopyText) ||\r\n (!field.toggleMask && field.isCopyText),\r\n 'pr-24': field.toggleMask && field.isCopyText && !field.hasGenerateKey,\r\n 'pr-32': field.toggleMask && field.isCopyText && field.hasGenerateKey,\r\n }\"\r\n [ngStyle]=\"{\r\n color: field.valueColor || 'inherit',\r\n 'font-size': field.valueSize || '',\r\n }\"\r\n />\r\n\r\n <div class=\"absolute right-0 top-1/2 -translate-y-1/2 flex items-center pr-3 gap-2\">\r\n @if (field.toggleMask && !field.isCopyText) {\r\n <span\r\n class=\"cursor-pointer\"\r\n (click)=\"togglePasswordVisibility()\"\r\n (keydown)=\"togglePasswordVisibility()\"\r\n >\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"showPassword ? 'eye-open' : 'eye-close'\"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"large\"\r\n data-icon-color=\"#03182b\"\r\n ></div>\r\n </span>\r\n } @else if (field.isCopyText && !field.toggleMask) {\r\n <span\r\n class=\"cursor-pointer\"\r\n (click)=\"copyText($event)\"\r\n (keydown)=\"copyText($event)\"\r\n >\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n data-icon-name=\"two-square\"\r\n data-icon-color=\"#03182b\"\r\n ></div>\r\n </span>\r\n @if (field.hasGenerateKey) {\r\n <span\r\n class=\"cursor-pointer\"\r\n (click)=\"field.onGenerateKey && field.onGenerateKey()\"\r\n (keydown)=\"field.onGenerateKey && field.onGenerateKey()\"\r\n >\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n data-icon-name=\"round-arrow-top-left\"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"large\"\r\n data-icon-color=\"#03182b\"\r\n ></div>\r\n </span>\r\n }\r\n } @else if (field.toggleMask && field.isCopyText) {\r\n <span\r\n class=\"cursor-pointer\"\r\n (click)=\"togglePasswordVisibility()\"\r\n (keydown)=\"togglePasswordVisibility()\"\r\n >\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"showPassword ? 'eye-open' : 'eye-close'\"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"large\"\r\n data-icon-color=\"#03182b\"\r\n ></div>\r\n </span>\r\n <span\r\n class=\"cursor-pointer\"\r\n (click)=\"copyText($event)\"\r\n (keydown)=\"copyText($event)\"\r\n >\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n data-icon-name=\"two-square\"\r\n data-icon-color=\"#03182b\"\r\n ></div>\r\n </span>\r\n @if (field.hasGenerateKey) {\r\n <span\r\n class=\"cursor-pointer\"\r\n (click)=\"field.onGenerateKey && field.onGenerateKey()\"\r\n (keydown)=\"field.onGenerateKey && field.onGenerateKey()\"\r\n [ngClass]=\"{ 'opacity-50 cursor-not-allowed': !control.value }\"\r\n >\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n data-icon-name=\"round-arrow-top-left\"\r\n data-icon-color=\"#03182b\"\r\n ></div>\r\n </span>\r\n }\r\n }\r\n </div>\r\n </div>\r\n\r\n @if (field.feedback && isPasswordFocused) {\r\n <div class=\"mt-2 space-y-1\">\r\n <div class=\"flex items-center justify-between text-xs\">\r\n <span class=\"font-medium\" [ngClass]=\"strengthClass\">\r\n {{ passwordStrengthLabel | translate }}\r\n </span>\r\n <div class=\"flex items-center gap-1\">\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"\r\n passwordStrengthPercent > 50 ? 'check-circle' : 'info-circle'\r\n \"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"extrasmall\"\r\n [attr.data-icon-color]=\"\r\n passwordStrengthPercent <= 25\r\n ? '#ef3e42'\r\n : passwordStrengthPercent <= 75\r\n ? '#ff9f00'\r\n : '#6cc24a'\r\n \"\r\n ></div>\r\n </div>\r\n </div>\r\n <div class=\"h-1.5 w-full bg-[#eef0f2] rounded-full overflow-hidden\">\r\n <div\r\n class=\"h-full transition-all duration-300 rounded-full\"\r\n [ngClass]=\"{\r\n 'bg-[#ef3e42]': passwordStrengthPercent <= 25,\r\n 'bg-[#ff9f00]': passwordStrengthPercent > 25 && passwordStrengthPercent <= 75,\r\n 'bg-[#6cc24a]': passwordStrengthPercent > 75,\r\n }\"\r\n [style.width.%]=\"passwordStrengthPercent\"\r\n ></div>\r\n </div>\r\n </div>\r\n }\r\n }\r\n\r\n <!-- Number Field -->\r\n @case ('number') {\r\n <div class=\"relative w-full\">\r\n @if (field.prefix?.icon) {\r\n <div class=\"absolute left-0 top-1/2 -translate-y-1/2 pl-3 flex items-center\">\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"field.prefix!.icon\"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"medium\"\r\n [attr.data-icon-color]=\"control.disabled ? '#c4cdd2' : '#03182b'\"\r\n ></div>\r\n </div>\r\n }\r\n <input\r\n [type]=\"field.type === 'number' && field.isCurrency ? 'text' : 'number'\"\r\n [name]=\"field.name\"\r\n [id]=\"uniqueId\"\r\n [required]=\"field.required || false\"\r\n [placeholder]=\"field.placeholder || '' | translate\"\r\n [disabled]=\"isDisabled || false\"\r\n [readOnly]=\"field.readOnly || false\"\r\n [formControl]=\"control\"\r\n [min]=\"field.type === 'number' && !field.isCurrency ? 0 : null\"\r\n [max]=\"field.type === 'number' && !field.isCurrency ? field.max : null\"\r\n [step]=\"field.type === 'number' && !field.isCurrency ? field.step || 1 : null\"\r\n (input)=\"handleNumberInput($event, field.minFractionDigits || 2)\"\r\n (paste)=\"handleNumberPaste($event, field.minFractionDigits || 2)\"\r\n (blur)=\"handleBlur($event, field.minFractionDigits || 2)\"\r\n (keydown)=\"handleNumberKeydown($event, field.isCurrency || false)\"\r\n class=\"fn-input-field\"\r\n [ngClass]=\"{\r\n disabled: control.disabled || field.readOnly,\r\n error: control.touched && control.errors,\r\n success: field['hasSuccessBorder'] && control.valid && !control.errors,\r\n 'pl-10': field.prefix?.icon,\r\n 'text-[24px] font-bold': field.isCurrency,\r\n }\"\r\n [ngStyle]=\"{\r\n color: field.valueColor || 'inherit',\r\n 'font-size': field.valueSize || '',\r\n }\"\r\n (focus)=\"onFocus()\"\r\n />\r\n </div>\r\n }\r\n\r\n <!-- Default Input Field (text, email, etc.) -->\r\n @default {\r\n <div class=\"relative z-0\">\r\n @if (field.prefix?.icon) {\r\n <div class=\"absolute left-0 top-1/2 -translate-y-1/2 pl-3 flex items-center\">\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"field.prefix!.icon\"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"medium\"\r\n [attr.data-icon-color]=\"control.disabled ? '#c4cdd2' : '#03182b'\"\r\n ></div>\r\n </div>\r\n }\r\n <input\r\n [type]=\"field.type\"\r\n [name]=\"field.name\"\r\n [id]=\"uniqueId\"\r\n [required]=\"field.required || false\"\r\n [placeholder]=\"field.placeholder || '' | translate\"\r\n [disabled]=\"field.disabled || false\"\r\n [readOnly]=\"field.readOnly || false\"\r\n [formControl]=\"control\"\r\n (input)=\"\r\n isEmailField\r\n ? handleEmailInput($event)\r\n : field.type === 'text' && isAlphanumeric\r\n ? handleAlphanumericInput($event)\r\n : handleInput($event)\r\n \"\r\n (blur)=\"handleBlur($event)\"\r\n class=\"fn-input-field\"\r\n [ngClass]=\"{\r\n disabled: control.disabled || field.readOnly,\r\n error: control.touched && control.errors,\r\n success: field['hasSuccessBorder'] && control.valid && !control.errors,\r\n 'pl-10': field.prefix?.icon,\r\n 'pr-10': (field.icon || field.suffix?.icon) && !field.isCopyText,\r\n 'pr-20':\r\n field.isCopyText && !field.hasGenerateKey && !(field.icon || field.suffix?.icon),\r\n 'pr-30':\r\n field.isCopyText && field.hasGenerateKey && !(field.icon || field.suffix?.icon),\r\n 'pr-32':\r\n field.isCopyText && field.hasGenerateKey && (field.icon || field.suffix?.icon),\r\n }\"\r\n [ngStyle]=\"{\r\n color: field.valueColor || 'inherit',\r\n 'font-size': field.valueSize || '',\r\n }\"\r\n (focus)=\"onFocus()\"\r\n />\r\n\r\n <div class=\"absolute right-0 top-1/2 -translate-y-1/2 flex items-center pr-3 gap-2\">\r\n @if (field.isCopyText) {\r\n <span\r\n class=\"cursor-pointer\"\r\n (click)=\"copyText($event)\"\r\n (keydown)=\"copyText($event)\"\r\n >\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n data-icon-name=\"two-square\"\r\n data-icon-color=\"#03182b\"\r\n ></div>\r\n </span>\r\n @if (field.hasGenerateKey) {\r\n <span\r\n class=\"cursor-pointer\"\r\n (click)=\"field.onGenerateKey && field.onGenerateKey()\"\r\n (keydown)=\"field.onGenerateKey && field.onGenerateKey()\"\r\n >\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n data-icon-name=\"round-arrow-top-left\"\r\n data-icon-color=\"#03182b\"\r\n ></div>\r\n </span>\r\n }\r\n }\r\n\r\n @if (field.icon || field.suffix?.icon) {\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"field.suffix?.icon || field.icon!.name\"\r\n [attr.data-icon-variant]=\"field.icon?.variant || 'Line'\"\r\n [attr.data-icon-size]=\"field.icon ? getIconSizeName(field.icon.size) : 'medium'\"\r\n [attr.data-icon-color]=\"control.disabled ? '#c4cdd2' : '#03182b'\"\r\n ></div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n }\r\n </ng-container>\r\n\r\n @if (showFormFieldMessage(control, helperText)) {\r\n <div class=\"fn-field-message-container\">\r\n <span\r\n class=\"fn-field-message-text\"\r\n [ngClass]=\"{\r\n error: isError,\r\n success: isSuccess,\r\n }\"\r\n >\r\n {{ getFieldMessage() | translate }}\r\n </span>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Integrated Toast Notifications -->\r\n <div class=\"toast-container\">\r\n @for (toast of toasts(); track toast.id) {\r\n <div class=\"toast toast-{{ toast.type }}\" [class.toast-enter]=\"toast.isVisible\">\r\n <span class=\"toast-icon\">\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"getToastIconName(toast)\"\r\n data-icon-variant=\"Colour\"\r\n data-icon-size=\"medium\"\r\n [attr.data-icon-color]=\"\r\n toast.type === 'success'\r\n ? '#6cc24a'\r\n : toast.type === 'warn'\r\n ? '#ff9f00'\r\n : toast.type === 'error'\r\n ? '#ef3e42'\r\n : '#03182b'\r\n \"\r\n ></div>\r\n </span>\r\n <div class=\"toast-content\">\r\n <span class=\"toast-message\">\r\n {{ getTranslatedMessage(toast.message) | translate }}\r\n </span>\r\n </div>\r\n <button class=\"toast-close\" (click)=\"removeToast(toast.id)\" aria-label=\"Close\">\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n data-icon-name=\"cross\"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"medium\"\r\n data-icon-color=\"#ffffff\"\r\n ></div>\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n}\r\n", styles: [".fn-input-container{display:flex;flex-direction:column;width:100%}.fn-label{font-family:Outfit,sans-serif;font-weight:500;margin-bottom:8px;display:flex;align-items:center}.fn-label span{color:#c4cdd2;font-size:14px;font-weight:400}.fn-input-field{width:100%;height:48px;padding:0 16px;background-color:#f7f8f9;border-bottom:1.5px solid #c4cdd2;font-family:Outfit,sans-serif;font-size:16px;color:#03182b;transition:all .2s ease;border-radius:4px 4px 0 0}.fn-input-field::placeholder{color:#c4cdd2}.fn-input-field:focus{outline:none;background-color:#fff;border-bottom-color:#03182b}.fn-input-field.error{border-bottom-color:#ef3e42}.fn-input-field.success{border-bottom-color:#6cc24a}.fn-input-field.disabled{background-color:#eef0f2;color:#c4cdd2;cursor:not-allowed}.fn-input-field.pl-10{padding-left:40px!important}.fn-input-field.pr-10{padding-right:40px!important}.fn-input-field.pr-12{padding-right:44px!important}.fn-input-field.pr-20{padding-right:72px!important}.fn-input-field.pr-24{padding-right:88px!important}.fn-input-field.pr-30{padding-right:104px!important}.fn-input-field.pr-32{padding-right:120px!important}.fn-field-message-container{margin-top:4px}.fn-field-message-text{font-family:Outfit,sans-serif;font-size:12px;color:#c4cdd2}.fn-field-message-text.error{color:#ef3e42}.fn-field-message-text.success{color:#6cc24a}.icon-container{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px}.relative{position:relative}.absolute{position:absolute}.right-0{right:0}.left-0{left:0}.top-1\\/2{top:50%}.-translate-y-1\\/2{transform:translateY(-50%)}.flex{display:flex}.items-center{align-items:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.pr-3{padding-right:.75rem}.pl-3{padding-left:.75rem}.mt-2{margin-top:.5rem}.space-y-1>:not([hidden])~:not([hidden]){margin-top:.25rem}.text-xs{font-size:.75rem}.font-medium{font-weight:500}.h-1\\.5{height:.375rem}.w-full{width:100%}.bg-\\[\\#eef0f2\\]{background-color:#eef0f2}.rounded-full{border-radius:9999px}.overflow-hidden{overflow:hidden}.transition-all{transition-property:all}.duration-300{transition-duration:.3s}.cursor-pointer{cursor:pointer}.opacity-50{opacity:.5}.cursor-not-allowed{cursor:not-allowed}.text-ellipsis{text-overflow:ellipsis}.toast-container{position:fixed;top:24px;left:50%;transform:translate(-50%);z-index:9999;width:100%;max-width:336px;display:flex;flex-direction:column;gap:8px;pointer-events:none}.toast{display:flex;align-items:center;background:#25333f;border-radius:8px;padding:12px;width:336px;max-width:100%;opacity:0;transform:translateY(-20px);transition:all .3s cubic-bezier(.4,0,.2,1);pointer-events:auto}.toast.toast-enter{opacity:1;transform:translateY(0)}.toast.toast-success{border-left:4px solid #6cc24a}.toast.toast-warn{border-left:4px solid #ff9f00}.toast.toast-error{border-left:4px solid #ef3e42}.toast.toast-info{border-left:4px solid #3b82f6}.toast .toast-icon{width:24px;height:24px;display:flex;align-items:center;justify-content:center;margin-right:8px;flex-shrink:0}.toast .toast-content{flex:1;min-width:0}.toast .toast-message{font-size:14px;line-height:20px;color:#fff;display:block}.toast .toast-close{background:none;border:none;font-size:20px;color:#fff;opacity:.7;cursor:pointer;padding:0;margin-left:8px;width:24px;height:24px;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:opacity .2s;pointer-events:auto}.toast .toast-close:hover{opacity:1}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1099
1153
  }
1100
1154
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FNInput, decorators: [{
1101
1155
  type: Component,
1102
- args: [{ selector: 'fn-input', standalone: true, imports: [FormsModule, CommonModule, ReactiveFormsModule, TranslateModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (field.name && isVisible() && !field.hidden) {\r\n <div class=\"fn-input-container\">\r\n @if (field.type! !== 'hidden') {\r\n <label\r\n [for]=\"uniqueId\"\r\n class=\"fn-label\"\r\n [ngStyle]=\"{\r\n color: field.color || '#03182b',\r\n 'font-size': field.labelSize || '',\r\n }\"\r\n >\r\n {{ getTranslatedLabel(field.label) }}\r\n @if (!field.required && !field.hideOptional) {\r\n <span>&nbsp;(Optional)</span>\r\n }\r\n </label>\r\n }\r\n\r\n <ng-container>\r\n @switch (field.type) {\r\n <!-- Textarea Field -->\r\n @case ('textarea') {\r\n <textarea\r\n #fnTextarea\r\n style=\"resize: none\"\r\n [name]=\"field.name\"\r\n [id]=\"uniqueId\"\r\n [required]=\"field.required || false\"\r\n [placeholder]=\"field.placeholder || '' | translate\"\r\n [disabled]=\"field.disabled || false\"\r\n [rows]=\"field.rows || 1\"\r\n [readonly]=\"field.readOnly || false\"\r\n [formControl]=\"control\"\r\n (input)=\"handleTextArea($event)\"\r\n (blur)=\"handleBlur($event)\"\r\n class=\"fn-input-field\"\r\n [ngClass]=\"{\r\n disabled: control.disabled || field.readOnly,\r\n error: control.touched && control.errors,\r\n success: field['hasSuccessBorder'] && control.valid && !control.errors,\r\n }\"\r\n [ngStyle]=\"{\r\n color: field.valueColor || 'inherit',\r\n 'font-size': field.valueSize || '',\r\n }\"\r\n (focus)=\"onFocus()\"\r\n ></textarea>\r\n }\r\n\r\n <!-- Password Field -->\r\n @case ('password') {\r\n <div class=\"relative w-full\">\r\n @if (field.prefix?.icon) {\r\n <div class=\"absolute left-0 top-1/2 -translate-y-1/2 pl-3 flex items-center\">\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"field.prefix!.icon\"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"medium\"\r\n [attr.data-icon-color]=\"control.disabled ? '#c4cdd2' : '#03182b'\"\r\n ></div>\r\n </div>\r\n }\r\n <input\r\n [type]=\"showPassword ? 'text' : 'password'\"\r\n [id]=\"uniqueId\"\r\n [required]=\"field.required || false\"\r\n [disabled]=\"field.disabled || false\"\r\n [formControl]=\"control\"\r\n [placeholder]=\"field.placeholder || '' | translate\"\r\n [readonly]=\"field.readOnly || false\"\r\n (input)=\"isAlphanumeric ? handleAlphanumericInput($event) : handleInput($event)\"\r\n (focus)=\"onPasswordFocus()\"\r\n (blur)=\"handlePasswordBlur($event)\"\r\n class=\"fn-input-field overflow-hidden text-ellipsis\"\r\n [ngClass]=\"{\r\n disabled: control.disabled || field.readOnly,\r\n error: control.touched && control.errors,\r\n success: field['hasSuccessBorder'] && control.valid,\r\n 'pl-10': field.prefix?.icon,\r\n 'pr-12':\r\n (field.toggleMask && !field.isCopyText) ||\r\n (!field.toggleMask && field.isCopyText),\r\n 'pr-24': field.toggleMask && field.isCopyText,\r\n 'pr-32': field.toggleMask && field.isCopyText && field.hasGenerateKey,\r\n }\"\r\n [ngStyle]=\"{\r\n color: field.valueColor || 'inherit',\r\n 'font-size': field.valueSize || '',\r\n }\"\r\n />\r\n\r\n <div class=\"absolute right-0 top-1/2 -translate-y-1/2 flex items-center pr-3 gap-2\">\r\n @if (field.toggleMask && !field.isCopyText) {\r\n <span\r\n class=\"cursor-pointer\"\r\n (click)=\"showPassword = !showPassword\"\r\n (keydown)=\"showPassword = !showPassword\"\r\n >\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"showPassword ? 'eye-open' : 'eye-close'\"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"large\"\r\n data-icon-color=\"#03182b\"\r\n ></div>\r\n </span>\r\n } @else if (field.isCopyText && !field.toggleMask) {\r\n <span\r\n class=\"cursor-pointer\"\r\n (click)=\"copyText($event)\"\r\n (keydown)=\"copyText($event)\"\r\n >\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n data-icon-name=\"two-square\"\r\n data-icon-color=\"#03182b\"\r\n ></div>\r\n </span>\r\n @if (field.hasGenerateKey) {\r\n <span\r\n class=\"cursor-pointer\"\r\n (click)=\"field.onGenerateKey && field.onGenerateKey()\"\r\n (keydown)=\"field.onGenerateKey && field.onGenerateKey()\"\r\n >\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n data-icon-name=\"two-square\"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"large\"\r\n data-icon-color=\"#03182b\"\r\n ></div>\r\n </span>\r\n }\r\n } @else if (field.toggleMask && field.isCopyText) {\r\n <span\r\n class=\"cursor-pointer\"\r\n (click)=\"showPassword = !showPassword\"\r\n (keydown)=\"showPassword = !showPassword\"\r\n >\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"showPassword ? 'eye-open' : 'eye-close'\"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"large\"\r\n data-icon-color=\"#03182b\"\r\n ></div>\r\n </span>\r\n <span\r\n class=\"cursor-pointer\"\r\n (click)=\"copyText($event)\"\r\n (keydown)=\"copyText($event)\"\r\n >\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n data-icon-name=\"two-square\"\r\n data-icon-color=\"#03182b\"\r\n ></div>\r\n </span>\r\n @if (field.hasGenerateKey) {\r\n <span\r\n class=\"cursor-pointer\"\r\n (click)=\"field.onGenerateKey && field.onGenerateKey()\"\r\n (keydown)=\"field.onGenerateKey && field.onGenerateKey()\"\r\n [ngClass]=\"{ 'opacity-50 cursor-not-allowed': !control.value }\"\r\n >\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n data-icon-name=\"round-arrow-top-left\"\r\n data-icon-color=\"#03182b\"\r\n ></div>\r\n </span>\r\n }\r\n }\r\n </div>\r\n </div>\r\n\r\n @if (field.feedback && isPasswordFocused) {\r\n <div class=\"mt-2 space-y-1\">\r\n <div class=\"flex items-center justify-between text-xs\">\r\n <span class=\"font-medium\" [ngClass]=\"strengthClass\">\r\n {{ passwordStrengthLabel | translate }}\r\n </span>\r\n <div class=\"flex items-center gap-1\">\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"\r\n passwordStrengthPercent > 50 ? 'check-circle' : 'info-circle'\r\n \"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"extrasmall\"\r\n [attr.data-icon-color]=\"\r\n passwordStrengthPercent <= 25\r\n ? '#ef3e42'\r\n : passwordStrengthPercent <= 75\r\n ? '#ff9f00'\r\n : '#6cc24a'\r\n \"\r\n ></div>\r\n </div>\r\n </div>\r\n <div class=\"h-1.5 w-full bg-[#eef0f2] rounded-full overflow-hidden\">\r\n <div\r\n class=\"h-full transition-all duration-300 rounded-full\"\r\n [ngClass]=\"{\r\n 'bg-[#ef3e42]': passwordStrengthPercent <= 25,\r\n 'bg-[#ff9f00]': passwordStrengthPercent > 25 && passwordStrengthPercent <= 75,\r\n 'bg-[#6cc24a]': passwordStrengthPercent > 75,\r\n }\"\r\n [style.width.%]=\"passwordStrengthPercent\"\r\n ></div>\r\n </div>\r\n </div>\r\n }\r\n }\r\n\r\n <!-- Number Field -->\r\n @case ('number') {\r\n <div class=\"relative w-full\">\r\n @if (field.prefix?.icon) {\r\n <div class=\"absolute left-0 top-1/2 -translate-y-1/2 pl-3 flex items-center\">\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"field.prefix!.icon\"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"medium\"\r\n [attr.data-icon-color]=\"control.disabled ? '#c4cdd2' : '#03182b'\"\r\n ></div>\r\n </div>\r\n }\r\n <input\r\n [type]=\"field.type === 'number' && field.isCurrency ? 'text' : 'number'\"\r\n [name]=\"field.name\"\r\n [id]=\"uniqueId\"\r\n [required]=\"field.required || false\"\r\n [placeholder]=\"field.placeholder || '' | translate\"\r\n [disabled]=\"isDisabled || false\"\r\n [readOnly]=\"field.readOnly || false\"\r\n [formControl]=\"control\"\r\n [min]=\"field.type === 'number' && !field.isCurrency ? 0 : null\"\r\n [max]=\"field.type === 'number' && !field.isCurrency ? field.max : null\"\r\n [step]=\"field.type === 'number' && !field.isCurrency ? field.step || 1 : null\"\r\n (input)=\"handleNumberInput($event, field.minFractionDigits || 2)\"\r\n (paste)=\"handleNumberPaste($event, field.minFractionDigits || 2)\"\r\n (blur)=\"handleBlur($event, field.minFractionDigits || 2)\"\r\n (keydown)=\"handleNumberKeydown($event, field.isCurrency || false)\"\r\n class=\"fn-input-field\"\r\n [ngClass]=\"{\r\n disabled: control.disabled || field.readOnly,\r\n error: control.touched && control.errors,\r\n success: field['hasSuccessBorder'] && control.valid && !control.errors,\r\n 'pl-10': field.prefix?.icon,\r\n 'text-[24px] font-bold': field.isCurrency,\r\n }\"\r\n [ngStyle]=\"{\r\n color: field.valueColor || 'inherit',\r\n 'font-size': field.valueSize || '',\r\n }\"\r\n (focus)=\"onFocus()\"\r\n />\r\n </div>\r\n }\r\n\r\n <!-- Default Input Field (text, email, etc.) -->\r\n @default {\r\n <div class=\"relative z-0\">\r\n @if (field.prefix?.icon) {\r\n <div class=\"absolute left-0 top-1/2 -translate-y-1/2 pl-3 flex items-center\">\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"field.prefix!.icon\"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"medium\"\r\n [attr.data-icon-color]=\"control.disabled ? '#c4cdd2' : '#03182b'\"\r\n ></div>\r\n </div>\r\n }\r\n <input\r\n [type]=\"field.type\"\r\n [name]=\"field.name\"\r\n [id]=\"uniqueId\"\r\n [required]=\"field.required || false\"\r\n [placeholder]=\"field.placeholder || '' | translate\"\r\n [disabled]=\"field.disabled || false\"\r\n [readOnly]=\"field.readOnly || false\"\r\n [formControl]=\"control\"\r\n (input)=\"\r\n isEmailField\r\n ? handleEmailInput($event)\r\n : field.type === 'text' && isAlphanumeric\r\n ? handleAlphanumericInput($event)\r\n : handleInput($event)\r\n \"\r\n (blur)=\"handleBlur($event)\"\r\n class=\"fn-input-field\"\r\n [ngClass]=\"{\r\n disabled: control.disabled || field.readOnly,\r\n error: control.touched && control.errors,\r\n success: field['hasSuccessBorder'] && control.valid && !control.errors,\r\n 'pl-10': field.prefix?.icon,\r\n 'pr-10': field.icon || field.suffix?.icon,\r\n }\"\r\n [ngStyle]=\"{\r\n color: field.valueColor || 'inherit',\r\n 'font-size': field.valueSize || '',\r\n }\"\r\n (focus)=\"onFocus()\"\r\n />\r\n @if (field.icon || field.suffix?.icon) {\r\n <span class=\"absolute right-0 top-1/2 -translate-y-1/2 pr-3 flex items-center\">\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"field.suffix?.icon || field.icon!.name\"\r\n [attr.data-icon-variant]=\"field.icon?.variant || 'Line'\"\r\n [attr.data-icon-size]=\"field.icon ? getIconSizeName(field.icon.size) : 'medium'\"\r\n [attr.data-icon-color]=\"control.disabled ? '#c4cdd2' : '#03182b'\"\r\n ></div>\r\n </span>\r\n }\r\n </div>\r\n }\r\n }\r\n </ng-container>\r\n\r\n @if (showFormFieldMessage(control, helperText)) {\r\n <div class=\"fn-field-message-container\">\r\n <span\r\n class=\"fn-field-message-text\"\r\n [ngClass]=\"{\r\n error: isError,\r\n success: isSuccess,\r\n }\"\r\n >\r\n {{ getFieldMessage() | translate }}\r\n </span>\r\n </div>\r\n }\r\n </div>\r\n}\r\n", styles: [".fn-input-container{display:flex;flex-direction:column;gap:8px;width:100%}.fn-label{color:#03182b;font-family:inherit;font-size:14px;font-weight:500;line-height:20px;margin-bottom:4px}.fn-input-field{background-color:#eff9fd;border:0!important;border-bottom:1px solid #c4cdd2!important;padding:8px 12px;width:100%;box-sizing:border-box;transition:border-color .2s ease-in-out;border-radius:0!important;appearance:none!important}.fn-input-field:focus{border-bottom:1px solid #0067b1!important;outline:none}.fn-input-field.error{border-bottom:1px solid #ef3e42!important}.fn-input-field.disabled{background-color:#eef0f2;color:#c4cdd2;cursor:not-allowed}.fn-input-field.pl-10{padding-left:36px!important}.fn-input-field.pr-10{padding-right:36px!important}.fn-input-field.pr-12{padding-right:44px!important}.fn-input-field.pr-24{padding-right:88px!important}.fn-input-field.pr-32{padding-right:120px!important}.icon-container{display:flex;align-items:center;justify-content:center;width:24px;height:24px;color:inherit}.fn-field-message-container{display:flex;align-items:center;gap:4px;margin-top:4px;min-height:20px}.fn-field-message-text{font-family:inherit;font-size:12px;font-weight:400;line-height:16px;color:#818c95}.fn-field-message-text.error{color:#ef3e42}.fn-field-message-text.success{color:#6cc24a}.mt-2{margin-top:.5rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * (1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.text-xs{font-size:.75rem;line-height:1rem}.font-medium{font-weight:500}.bg-\\[\\#eef0f2\\]{background-color:#eef0f2}.bg-\\[\\#ef3e42\\]{background-color:#ef3e42}.bg-\\[\\#ff9f00\\]{background-color:#ff9f00}.bg-\\[\\#6cc24a\\]{background-color:#6cc24a}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-300{transition-duration:.3s}.rounded-full{border-radius:9999px}.overflow-hidden{overflow:hidden}.h-1\\.5{height:.375rem}.w-full{width:100%}.flex{display:flex}.items-center{align-items:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.pl-3{padding-left:.75rem}.pr-3{padding-right:.75rem}.absolute{position:absolute}.right-0{right:0}.left-0{left:0}.top-1\\/2{top:50%}.-translate-y-1\\/2{transform:translateY(-50%)}.z-0{z-index:0}.relative{position:relative}.cursor-pointer{cursor:pointer}.text-ellipsis{text-overflow:ellipsis}\n"] }]
1156
+ args: [{ selector: 'fn-input', standalone: true, imports: [FormsModule, CommonModule, ReactiveFormsModule, TranslateModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (field.name && isVisible() && !field.hidden) {\r\n <div class=\"fn-input-container\">\r\n @if (field.type! !== 'hidden') {\r\n <label\r\n [for]=\"uniqueId\"\r\n class=\"fn-label\"\r\n [ngStyle]=\"{\r\n color: field.color || '#03182b',\r\n 'font-size': field.labelSize || '',\r\n }\"\r\n >\r\n {{ getTranslatedLabel(field.label) }}\r\n @if (!field.required && !field.hideOptional) {\r\n <span>&nbsp;(Optional)</span>\r\n }\r\n </label>\r\n }\r\n\r\n <ng-container>\r\n @switch (field.type) {\r\n <!-- Textarea Field -->\r\n @case ('textarea') {\r\n <textarea\r\n #fnTextarea\r\n style=\"resize: none\"\r\n [name]=\"field.name\"\r\n [id]=\"uniqueId\"\r\n [required]=\"field.required || false\"\r\n [placeholder]=\"field.placeholder || '' | translate\"\r\n [disabled]=\"field.disabled || false\"\r\n [rows]=\"field.rows || 1\"\r\n [readonly]=\"field.readOnly || false\"\r\n [formControl]=\"control\"\r\n (input)=\"handleTextArea($event)\"\r\n (blur)=\"handleBlur($event)\"\r\n class=\"fn-input-field\"\r\n [ngClass]=\"{\r\n disabled: control.disabled || field.readOnly,\r\n error: control.touched && control.errors,\r\n success: field['hasSuccessBorder'] && control.valid && !control.errors,\r\n }\"\r\n [ngStyle]=\"{\r\n color: field.valueColor || 'inherit',\r\n 'font-size': field.valueSize || '',\r\n }\"\r\n (focus)=\"onFocus()\"\r\n ></textarea>\r\n }\r\n\r\n <!-- Password Field -->\r\n @case ('password') {\r\n <div class=\"relative w-full\">\r\n @if (field.prefix?.icon) {\r\n <div class=\"absolute left-0 top-1/2 -translate-y-1/2 pl-3 flex items-center\">\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"field.prefix!.icon\"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"medium\"\r\n [attr.data-icon-color]=\"control.disabled ? '#c4cdd2' : '#03182b'\"\r\n ></div>\r\n </div>\r\n }\r\n <input\r\n [type]=\"showPassword ? 'text' : 'password'\"\r\n [id]=\"uniqueId\"\r\n [required]=\"field.required || false\"\r\n [disabled]=\"field.disabled || false\"\r\n [formControl]=\"control\"\r\n [placeholder]=\"field.placeholder || '' | translate\"\r\n [readonly]=\"field.readOnly || false\"\r\n (input)=\"isAlphanumeric ? handleAlphanumericInput($event) : handleInput($event)\"\r\n (focus)=\"onPasswordFocus()\"\r\n (blur)=\"handlePasswordBlur($event)\"\r\n class=\"fn-input-field overflow-hidden text-ellipsis\"\r\n [ngClass]=\"{\r\n disabled: control.disabled || field.readOnly,\r\n error: control.touched && control.errors,\r\n success: field['hasSuccessBorder'] && control.valid,\r\n 'pl-10': field.prefix?.icon,\r\n 'pr-12':\r\n (field.toggleMask && !field.isCopyText) ||\r\n (!field.toggleMask && field.isCopyText),\r\n 'pr-24': field.toggleMask && field.isCopyText && !field.hasGenerateKey,\r\n 'pr-32': field.toggleMask && field.isCopyText && field.hasGenerateKey,\r\n }\"\r\n [ngStyle]=\"{\r\n color: field.valueColor || 'inherit',\r\n 'font-size': field.valueSize || '',\r\n }\"\r\n />\r\n\r\n <div class=\"absolute right-0 top-1/2 -translate-y-1/2 flex items-center pr-3 gap-2\">\r\n @if (field.toggleMask && !field.isCopyText) {\r\n <span\r\n class=\"cursor-pointer\"\r\n (click)=\"togglePasswordVisibility()\"\r\n (keydown)=\"togglePasswordVisibility()\"\r\n >\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"showPassword ? 'eye-open' : 'eye-close'\"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"large\"\r\n data-icon-color=\"#03182b\"\r\n ></div>\r\n </span>\r\n } @else if (field.isCopyText && !field.toggleMask) {\r\n <span\r\n class=\"cursor-pointer\"\r\n (click)=\"copyText($event)\"\r\n (keydown)=\"copyText($event)\"\r\n >\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n data-icon-name=\"two-square\"\r\n data-icon-color=\"#03182b\"\r\n ></div>\r\n </span>\r\n @if (field.hasGenerateKey) {\r\n <span\r\n class=\"cursor-pointer\"\r\n (click)=\"field.onGenerateKey && field.onGenerateKey()\"\r\n (keydown)=\"field.onGenerateKey && field.onGenerateKey()\"\r\n >\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n data-icon-name=\"round-arrow-top-left\"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"large\"\r\n data-icon-color=\"#03182b\"\r\n ></div>\r\n </span>\r\n }\r\n } @else if (field.toggleMask && field.isCopyText) {\r\n <span\r\n class=\"cursor-pointer\"\r\n (click)=\"togglePasswordVisibility()\"\r\n (keydown)=\"togglePasswordVisibility()\"\r\n >\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"showPassword ? 'eye-open' : 'eye-close'\"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"large\"\r\n data-icon-color=\"#03182b\"\r\n ></div>\r\n </span>\r\n <span\r\n class=\"cursor-pointer\"\r\n (click)=\"copyText($event)\"\r\n (keydown)=\"copyText($event)\"\r\n >\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n data-icon-name=\"two-square\"\r\n data-icon-color=\"#03182b\"\r\n ></div>\r\n </span>\r\n @if (field.hasGenerateKey) {\r\n <span\r\n class=\"cursor-pointer\"\r\n (click)=\"field.onGenerateKey && field.onGenerateKey()\"\r\n (keydown)=\"field.onGenerateKey && field.onGenerateKey()\"\r\n [ngClass]=\"{ 'opacity-50 cursor-not-allowed': !control.value }\"\r\n >\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n data-icon-name=\"round-arrow-top-left\"\r\n data-icon-color=\"#03182b\"\r\n ></div>\r\n </span>\r\n }\r\n }\r\n </div>\r\n </div>\r\n\r\n @if (field.feedback && isPasswordFocused) {\r\n <div class=\"mt-2 space-y-1\">\r\n <div class=\"flex items-center justify-between text-xs\">\r\n <span class=\"font-medium\" [ngClass]=\"strengthClass\">\r\n {{ passwordStrengthLabel | translate }}\r\n </span>\r\n <div class=\"flex items-center gap-1\">\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"\r\n passwordStrengthPercent > 50 ? 'check-circle' : 'info-circle'\r\n \"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"extrasmall\"\r\n [attr.data-icon-color]=\"\r\n passwordStrengthPercent <= 25\r\n ? '#ef3e42'\r\n : passwordStrengthPercent <= 75\r\n ? '#ff9f00'\r\n : '#6cc24a'\r\n \"\r\n ></div>\r\n </div>\r\n </div>\r\n <div class=\"h-1.5 w-full bg-[#eef0f2] rounded-full overflow-hidden\">\r\n <div\r\n class=\"h-full transition-all duration-300 rounded-full\"\r\n [ngClass]=\"{\r\n 'bg-[#ef3e42]': passwordStrengthPercent <= 25,\r\n 'bg-[#ff9f00]': passwordStrengthPercent > 25 && passwordStrengthPercent <= 75,\r\n 'bg-[#6cc24a]': passwordStrengthPercent > 75,\r\n }\"\r\n [style.width.%]=\"passwordStrengthPercent\"\r\n ></div>\r\n </div>\r\n </div>\r\n }\r\n }\r\n\r\n <!-- Number Field -->\r\n @case ('number') {\r\n <div class=\"relative w-full\">\r\n @if (field.prefix?.icon) {\r\n <div class=\"absolute left-0 top-1/2 -translate-y-1/2 pl-3 flex items-center\">\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"field.prefix!.icon\"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"medium\"\r\n [attr.data-icon-color]=\"control.disabled ? '#c4cdd2' : '#03182b'\"\r\n ></div>\r\n </div>\r\n }\r\n <input\r\n [type]=\"field.type === 'number' && field.isCurrency ? 'text' : 'number'\"\r\n [name]=\"field.name\"\r\n [id]=\"uniqueId\"\r\n [required]=\"field.required || false\"\r\n [placeholder]=\"field.placeholder || '' | translate\"\r\n [disabled]=\"isDisabled || false\"\r\n [readOnly]=\"field.readOnly || false\"\r\n [formControl]=\"control\"\r\n [min]=\"field.type === 'number' && !field.isCurrency ? 0 : null\"\r\n [max]=\"field.type === 'number' && !field.isCurrency ? field.max : null\"\r\n [step]=\"field.type === 'number' && !field.isCurrency ? field.step || 1 : null\"\r\n (input)=\"handleNumberInput($event, field.minFractionDigits || 2)\"\r\n (paste)=\"handleNumberPaste($event, field.minFractionDigits || 2)\"\r\n (blur)=\"handleBlur($event, field.minFractionDigits || 2)\"\r\n (keydown)=\"handleNumberKeydown($event, field.isCurrency || false)\"\r\n class=\"fn-input-field\"\r\n [ngClass]=\"{\r\n disabled: control.disabled || field.readOnly,\r\n error: control.touched && control.errors,\r\n success: field['hasSuccessBorder'] && control.valid && !control.errors,\r\n 'pl-10': field.prefix?.icon,\r\n 'text-[24px] font-bold': field.isCurrency,\r\n }\"\r\n [ngStyle]=\"{\r\n color: field.valueColor || 'inherit',\r\n 'font-size': field.valueSize || '',\r\n }\"\r\n (focus)=\"onFocus()\"\r\n />\r\n </div>\r\n }\r\n\r\n <!-- Default Input Field (text, email, etc.) -->\r\n @default {\r\n <div class=\"relative z-0\">\r\n @if (field.prefix?.icon) {\r\n <div class=\"absolute left-0 top-1/2 -translate-y-1/2 pl-3 flex items-center\">\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"field.prefix!.icon\"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"medium\"\r\n [attr.data-icon-color]=\"control.disabled ? '#c4cdd2' : '#03182b'\"\r\n ></div>\r\n </div>\r\n }\r\n <input\r\n [type]=\"field.type\"\r\n [name]=\"field.name\"\r\n [id]=\"uniqueId\"\r\n [required]=\"field.required || false\"\r\n [placeholder]=\"field.placeholder || '' | translate\"\r\n [disabled]=\"field.disabled || false\"\r\n [readOnly]=\"field.readOnly || false\"\r\n [formControl]=\"control\"\r\n (input)=\"\r\n isEmailField\r\n ? handleEmailInput($event)\r\n : field.type === 'text' && isAlphanumeric\r\n ? handleAlphanumericInput($event)\r\n : handleInput($event)\r\n \"\r\n (blur)=\"handleBlur($event)\"\r\n class=\"fn-input-field\"\r\n [ngClass]=\"{\r\n disabled: control.disabled || field.readOnly,\r\n error: control.touched && control.errors,\r\n success: field['hasSuccessBorder'] && control.valid && !control.errors,\r\n 'pl-10': field.prefix?.icon,\r\n 'pr-10': (field.icon || field.suffix?.icon) && !field.isCopyText,\r\n 'pr-20':\r\n field.isCopyText && !field.hasGenerateKey && !(field.icon || field.suffix?.icon),\r\n 'pr-30':\r\n field.isCopyText && field.hasGenerateKey && !(field.icon || field.suffix?.icon),\r\n 'pr-32':\r\n field.isCopyText && field.hasGenerateKey && (field.icon || field.suffix?.icon),\r\n }\"\r\n [ngStyle]=\"{\r\n color: field.valueColor || 'inherit',\r\n 'font-size': field.valueSize || '',\r\n }\"\r\n (focus)=\"onFocus()\"\r\n />\r\n\r\n <div class=\"absolute right-0 top-1/2 -translate-y-1/2 flex items-center pr-3 gap-2\">\r\n @if (field.isCopyText) {\r\n <span\r\n class=\"cursor-pointer\"\r\n (click)=\"copyText($event)\"\r\n (keydown)=\"copyText($event)\"\r\n >\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n data-icon-name=\"two-square\"\r\n data-icon-color=\"#03182b\"\r\n ></div>\r\n </span>\r\n @if (field.hasGenerateKey) {\r\n <span\r\n class=\"cursor-pointer\"\r\n (click)=\"field.onGenerateKey && field.onGenerateKey()\"\r\n (keydown)=\"field.onGenerateKey && field.onGenerateKey()\"\r\n >\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n data-icon-name=\"round-arrow-top-left\"\r\n data-icon-color=\"#03182b\"\r\n ></div>\r\n </span>\r\n }\r\n }\r\n\r\n @if (field.icon || field.suffix?.icon) {\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"field.suffix?.icon || field.icon!.name\"\r\n [attr.data-icon-variant]=\"field.icon?.variant || 'Line'\"\r\n [attr.data-icon-size]=\"field.icon ? getIconSizeName(field.icon.size) : 'medium'\"\r\n [attr.data-icon-color]=\"control.disabled ? '#c4cdd2' : '#03182b'\"\r\n ></div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n }\r\n </ng-container>\r\n\r\n @if (showFormFieldMessage(control, helperText)) {\r\n <div class=\"fn-field-message-container\">\r\n <span\r\n class=\"fn-field-message-text\"\r\n [ngClass]=\"{\r\n error: isError,\r\n success: isSuccess,\r\n }\"\r\n >\r\n {{ getFieldMessage() | translate }}\r\n </span>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Integrated Toast Notifications -->\r\n <div class=\"toast-container\">\r\n @for (toast of toasts(); track toast.id) {\r\n <div class=\"toast toast-{{ toast.type }}\" [class.toast-enter]=\"toast.isVisible\">\r\n <span class=\"toast-icon\">\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n [attr.data-icon-name]=\"getToastIconName(toast)\"\r\n data-icon-variant=\"Colour\"\r\n data-icon-size=\"medium\"\r\n [attr.data-icon-color]=\"\r\n toast.type === 'success'\r\n ? '#6cc24a'\r\n : toast.type === 'warn'\r\n ? '#ff9f00'\r\n : toast.type === 'error'\r\n ? '#ef3e42'\r\n : '#03182b'\r\n \"\r\n ></div>\r\n </span>\r\n <div class=\"toast-content\">\r\n <span class=\"toast-message\">\r\n {{ getTranslatedMessage(toast.message) | translate }}\r\n </span>\r\n </div>\r\n <button class=\"toast-close\" (click)=\"removeToast(toast.id)\" aria-label=\"Close\">\r\n <div\r\n #iconContainer\r\n class=\"icon-container\"\r\n data-icon-name=\"cross\"\r\n data-icon-variant=\"Line\"\r\n data-icon-size=\"medium\"\r\n data-icon-color=\"#ffffff\"\r\n ></div>\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n}\r\n", styles: [".fn-input-container{display:flex;flex-direction:column;width:100%}.fn-label{font-family:Outfit,sans-serif;font-weight:500;margin-bottom:8px;display:flex;align-items:center}.fn-label span{color:#c4cdd2;font-size:14px;font-weight:400}.fn-input-field{width:100%;height:48px;padding:0 16px;background-color:#f7f8f9;border-bottom:1.5px solid #c4cdd2;font-family:Outfit,sans-serif;font-size:16px;color:#03182b;transition:all .2s ease;border-radius:4px 4px 0 0}.fn-input-field::placeholder{color:#c4cdd2}.fn-input-field:focus{outline:none;background-color:#fff;border-bottom-color:#03182b}.fn-input-field.error{border-bottom-color:#ef3e42}.fn-input-field.success{border-bottom-color:#6cc24a}.fn-input-field.disabled{background-color:#eef0f2;color:#c4cdd2;cursor:not-allowed}.fn-input-field.pl-10{padding-left:40px!important}.fn-input-field.pr-10{padding-right:40px!important}.fn-input-field.pr-12{padding-right:44px!important}.fn-input-field.pr-20{padding-right:72px!important}.fn-input-field.pr-24{padding-right:88px!important}.fn-input-field.pr-30{padding-right:104px!important}.fn-input-field.pr-32{padding-right:120px!important}.fn-field-message-container{margin-top:4px}.fn-field-message-text{font-family:Outfit,sans-serif;font-size:12px;color:#c4cdd2}.fn-field-message-text.error{color:#ef3e42}.fn-field-message-text.success{color:#6cc24a}.icon-container{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px}.relative{position:relative}.absolute{position:absolute}.right-0{right:0}.left-0{left:0}.top-1\\/2{top:50%}.-translate-y-1\\/2{transform:translateY(-50%)}.flex{display:flex}.items-center{align-items:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.pr-3{padding-right:.75rem}.pl-3{padding-left:.75rem}.mt-2{margin-top:.5rem}.space-y-1>:not([hidden])~:not([hidden]){margin-top:.25rem}.text-xs{font-size:.75rem}.font-medium{font-weight:500}.h-1\\.5{height:.375rem}.w-full{width:100%}.bg-\\[\\#eef0f2\\]{background-color:#eef0f2}.rounded-full{border-radius:9999px}.overflow-hidden{overflow:hidden}.transition-all{transition-property:all}.duration-300{transition-duration:.3s}.cursor-pointer{cursor:pointer}.opacity-50{opacity:.5}.cursor-not-allowed{cursor:not-allowed}.text-ellipsis{text-overflow:ellipsis}.toast-container{position:fixed;top:24px;left:50%;transform:translate(-50%);z-index:9999;width:100%;max-width:336px;display:flex;flex-direction:column;gap:8px;pointer-events:none}.toast{display:flex;align-items:center;background:#25333f;border-radius:8px;padding:12px;width:336px;max-width:100%;opacity:0;transform:translateY(-20px);transition:all .3s cubic-bezier(.4,0,.2,1);pointer-events:auto}.toast.toast-enter{opacity:1;transform:translateY(0)}.toast.toast-success{border-left:4px solid #6cc24a}.toast.toast-warn{border-left:4px solid #ff9f00}.toast.toast-error{border-left:4px solid #ef3e42}.toast.toast-info{border-left:4px solid #3b82f6}.toast .toast-icon{width:24px;height:24px;display:flex;align-items:center;justify-content:center;margin-right:8px;flex-shrink:0}.toast .toast-content{flex:1;min-width:0}.toast .toast-message{font-size:14px;line-height:20px;color:#fff;display:block}.toast .toast-close{background:none;border:none;font-size:20px;color:#fff;opacity:.7;cursor:pointer;padding:0;margin-left:8px;width:24px;height:24px;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:opacity .2s;pointer-events:auto}.toast .toast-close:hover{opacity:1}\n"] }]
1103
1157
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { field: [{
1104
1158
  type: Input
1105
1159
  }], helperHandle: [{
@@ -1128,5 +1182,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
1128
1182
  * Generated bundle index. Do not edit.
1129
1183
  */
1130
1184
 
1131
- export { DEFAULT_CURRENCY_META, FNInput };
1185
+ export { DEFAULT_CURRENCY_META, FNInput, FN_TOAST_SERVICE };
1132
1186
  //# sourceMappingURL=fn-input.mjs.map