@ng-nest/ui 21.0.4 → 21.0.6
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/fesm2022/ng-nest-ui-base-form.mjs +2 -1
- package/fesm2022/ng-nest-ui-base-form.mjs.map +1 -1
- package/fesm2022/ng-nest-ui-bubble.mjs +141 -129
- package/fesm2022/ng-nest-ui-bubble.mjs.map +1 -1
- package/fesm2022/ng-nest-ui-dialog.mjs +49 -45
- package/fesm2022/ng-nest-ui-dialog.mjs.map +1 -1
- package/fesm2022/ng-nest-ui-dropdown.mjs +2 -2
- package/fesm2022/ng-nest-ui-dropdown.mjs.map +1 -1
- package/fesm2022/ng-nest-ui-form.mjs +16 -4
- package/fesm2022/ng-nest-ui-form.mjs.map +1 -1
- package/fesm2022/ng-nest-ui-i18n.mjs +5 -5
- package/fesm2022/ng-nest-ui-i18n.mjs.map +1 -1
- package/fesm2022/ng-nest-ui-image.mjs +37 -25
- package/fesm2022/ng-nest-ui-image.mjs.map +1 -1
- package/fesm2022/ng-nest-ui-input.mjs +12 -2
- package/fesm2022/ng-nest-ui-input.mjs.map +1 -1
- package/fesm2022/ng-nest-ui-list.mjs +3 -0
- package/fesm2022/ng-nest-ui-list.mjs.map +1 -1
- package/fesm2022/ng-nest-ui-menu.mjs +16 -4
- package/fesm2022/ng-nest-ui-menu.mjs.map +1 -1
- package/fesm2022/ng-nest-ui-message-box.mjs.map +1 -1
- package/fesm2022/ng-nest-ui-message.mjs.map +1 -1
- package/fesm2022/ng-nest-ui-notification.mjs.map +1 -1
- package/fesm2022/ng-nest-ui-scrollable.mjs +14 -6
- package/fesm2022/ng-nest-ui-scrollable.mjs.map +1 -1
- package/fesm2022/ng-nest-ui-table-view.mjs +277 -243
- package/fesm2022/ng-nest-ui-table-view.mjs.map +1 -1
- package/fesm2022/ng-nest-ui-table.mjs +18 -6
- package/fesm2022/ng-nest-ui-table.mjs.map +1 -1
- package/fesm2022/ng-nest-ui-tree.mjs +37 -19
- package/fesm2022/ng-nest-ui-tree.mjs.map +1 -1
- package/package.json +1 -1
- package/types/ng-nest-ui-bubble.d.ts +12 -7
- package/types/ng-nest-ui-dialog.d.ts +170 -102
- package/types/ng-nest-ui-form.d.ts +15 -3
- package/types/ng-nest-ui-i18n.d.ts +23 -24
- package/types/ng-nest-ui-image.d.ts +28 -13
- package/types/ng-nest-ui-input.d.ts +1 -0
- package/types/ng-nest-ui-list.d.ts +31 -20
- package/types/ng-nest-ui-menu.d.ts +15 -3
- package/types/ng-nest-ui-message-box.d.ts +16 -3
- package/types/ng-nest-ui-message.d.ts +15 -3
- package/types/ng-nest-ui-notification.d.ts +15 -3
- package/types/ng-nest-ui-scrollable.d.ts +4 -2
- package/types/ng-nest-ui-table-view.d.ts +99 -65
- package/types/ng-nest-ui-table.d.ts +60 -5
- package/types/ng-nest-ui-tree.d.ts +29 -3
|
@@ -140,7 +140,8 @@ function XFormControlFunction(configName) {
|
|
|
140
140
|
this.config = inject(XConfigService).getConfigForComponent(configName);
|
|
141
141
|
this.cdr = inject(ChangeDetectorRef);
|
|
142
142
|
this.invalid = computed(() => {
|
|
143
|
-
return (this.validatorComputed() &&
|
|
143
|
+
return (this.validatorComputed() &&
|
|
144
|
+
((!XIsEmpty(this.value()) && this.invalidPattern()) || this.requiredIsEmpty() || this.invalidInputValidator()));
|
|
144
145
|
}, ...(ngDevMode ? [{ debugName: "invalid" }] : []));
|
|
145
146
|
this.invalidPattern = computed(() => {
|
|
146
147
|
const pattern = this.patternComputed();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ng-nest-ui-base-form.mjs","sources":["../../../../lib/ng-nest/ui/base-form/base-form.property.ts","../../../../lib/ng-nest/ui/base-form/base-form.component.ts","../../../../lib/ng-nest/ui/base-form/base-form.module.ts","../../../../lib/ng-nest/ui/base-form/ng-nest-ui-base-form.ts"],"sourcesContent":["import { Component, TemplateRef, input, model } from '@angular/core';\r\nimport {\r\n XAlign,\r\n XBoolean,\r\n XDirection,\r\n XJustify,\r\n XNumber,\r\n XProperty,\r\n XSize,\r\n XTemplate,\r\n XToBoolean,\r\n XToCssPixelValue\r\n} from '@ng-nest/ui/core';\r\n\r\n/**\r\n * 表单对象共有的参数\r\n */\r\nexport interface XFormOption {\r\n /**\r\n * 标签\r\n */\r\n label?: any;\r\n /**\r\n * 标签宽度\r\n */\r\n labelWidth?: string;\r\n /**\r\n * 标签文字对齐方式\r\n */\r\n labelAlign?: XAlign;\r\n /**\r\n * flex 布局下的子元素水平排列方式\r\n */\r\n justify?: XJustify;\r\n /**\r\n * flex 布局下的子元素垂直排列方式\r\n */\r\n align?: XAlign;\r\n /**\r\n * flex 布局下的子元素排列方向\r\n */\r\n direction?: XDirection;\r\n /**\r\n * 尺寸\r\n */\r\n size?: XSize;\r\n /**\r\n * 输入提示信息\r\n */\r\n placeholder?: string | string[];\r\n /**\r\n * 禁用\r\n */\r\n disabled?: boolean;\r\n /**\r\n * 必填\r\n */\r\n required?: boolean;\r\n /**\r\n * 正则验证规则\r\n */\r\n pattern?: RegExp | RegExp[];\r\n /**\r\n * 验证不通过提示文字\r\n */\r\n message?: string | string[];\r\n /**\r\n * 激活状态\r\n */\r\n active?: boolean;\r\n /**\r\n * 输入框点击样式\r\n */\r\n pointer?: boolean;\r\n /**\r\n * 输入验证函数\r\n */\r\n inputValidator?: (value: any) => boolean;\r\n}\r\n\r\n/**\r\n * 表单对象共有的参数\r\n */\r\n@Component({ selector: 'x-formcontrol-prop', template: '' })\r\nexport class XFormControlProp extends XProperty {\r\n /**\r\n * @zh_CN 初始启用验证,在输入值都自动开启\r\n * @en_US Initial enable validation, which is automatically enabled when the input value is\r\n */\r\n readonly validator = input<boolean, XBoolean>(false, { transform: XToBoolean });\r\n /**\r\n * @zh_CN 标签\r\n * @en_US Label\r\n */\r\n readonly label = input<XTemplate>('');\r\n /**\r\n * @zh_CN 标签宽度\r\n * @en_US Label width\r\n */\r\n readonly labelWidth = input<string, XNumber>('', { transform: XToCssPixelValue });\r\n /**\r\n * @zh_CN 标签文字对齐方式\r\n * @en_US Label text alignment method\r\n */\r\n readonly labelAlign = input<XAlign>('start');\r\n /**\r\n * @zh_CN flex 布局下的子元素水平排列方式\r\n * @en_US The level of sub-element level arrangement under flex layout\r\n */\r\n readonly justify = input<XJustify>('start');\r\n /**\r\n * @zh_CN flex 布局下的子元素垂直排列方式\r\n * @en_US sub-element vertical arrangement method under flex layout\r\n */\r\n readonly align = input<XAlign>('start');\r\n /**\r\n * @zh_CN flex 布局下的子元素排列方向\r\n * @en_US The direction of the sub-element arrangement under flex layout\r\n */\r\n readonly direction = input<XDirection>('column');\r\n /**\r\n * @zh_CN 尺寸\r\n * @en_US Size\r\n */\r\n readonly size = input<XSize>('medium');\r\n /**\r\n * @zh_CN 输入提示信息\r\n * @en_US Enter prompt information\r\n */\r\n readonly placeholder = input<string | string[]>('');\r\n /**\r\n * @zh_CN 禁用\r\n * @en_US Disabled\r\n */\r\n readonly disabled = input<boolean, XBoolean>(false, { transform: XToBoolean });\r\n /**\r\n * @zh_CN 必填\r\n * @en_US Required\r\n */\r\n readonly required = input<boolean, XBoolean>(false, { transform: XToBoolean });\r\n /**\r\n * @zh_CN 只读\r\n * @en_US Readonly\r\n */\r\n readonly readonly = input<boolean, XBoolean>(false, { transform: XToBoolean });\r\n /**\r\n * @zh_CN 值模板\r\n * @en_US Node template\r\n */\r\n readonly valueTpl = input<TemplateRef<any>>();\r\n /**\r\n * @zh_CN 值模板参数\r\n * @en_US Node template\r\n */\r\n readonly valueTplContext = input();\r\n /**\r\n * @zh_CN 前置标签\r\n * @en_US Before label\r\n */\r\n readonly before = input<XTemplate>();\r\n /**\r\n * @zh_CN 后置标签\r\n * @en_US After label\r\n */\r\n readonly after = input<XTemplate>();\r\n /**\r\n * @zh_CN 正则验证规则\r\n * @en_US Regular verification rules\r\n */\r\n readonly pattern = input<RegExp | RegExp[]>([]);\r\n /**\r\n * @zh_CN 验证不通过提示文字\r\n * @en_US Verify not pass the prompt text\r\n */\r\n readonly message = input<string | string[]>([]);\r\n /**\r\n * @zh_CN 激活状态\r\n * @en_US Activation state\r\n */\r\n readonly active = model<boolean>(false);\r\n /**\r\n * @zh_CN 输入框点击样式\r\n * @en_US Enter box click style\r\n */\r\n readonly pointer = input<boolean, XBoolean>(false, { transform: XToBoolean });\r\n /**\r\n * @zh_CN 输入验证函数\r\n * @en_US Enter the verification function\r\n */\r\n readonly inputValidator = input<(value: any) => boolean>();\r\n}\r\n","import {\r\n AbstractControl,\r\n ControlValueAccessor,\r\n NG_VALUE_ACCESSOR,\r\n ValidationErrors,\r\n ValidatorFn\r\n} from '@angular/forms';\r\nimport { ChangeDetectorRef, computed, forwardRef, inject, signal, Type } from '@angular/core';\r\nimport { XIsEmpty, XIsUndefined, XComponentConfigKey, XConfigService, XIsNull } from '@ng-nest/ui/core';\r\nimport { XFormControlProp } from './base-form.property';\r\nimport { toObservable } from '@angular/core/rxjs-interop';\r\n\r\nexport function XValueAccessor<T>(component: Type<T>) {\r\n return { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => component), multi: true };\r\n}\r\n\r\nexport function XFormInputValidator(func: (value: any) => boolean): ValidatorFn {\r\n return (control: AbstractControl): ValidationErrors | null => {\r\n const invalid = func ? !func(control.value) : null;\r\n return invalid ? { inputValidator: true } : null;\r\n };\r\n}\r\n\r\nexport function XFormControlFunction<C extends XComponentConfigKey>(configName: C) {\r\n return class XFormControlFun extends XFormControlProp implements ControlValueAccessor {\r\n config = inject(XConfigService).getConfigForComponent(configName);\r\n cdr = inject(ChangeDetectorRef);\r\n invalid = computed(() => {\r\n return (\r\n this.validatorComputed() && ((!XIsEmpty(this.value()) && this.invalidPattern()) || this.invalidInputValidator())\r\n );\r\n });\r\n invalidPattern = computed(() => {\r\n const pattern = this.patternComputed();\r\n if (!this.validatorComputed() || XIsUndefined(pattern) || XIsNull(pattern)) return false;\r\n let result = false;\r\n let index = 0;\r\n\r\n if (Array.isArray(pattern)) {\r\n for (const pt of pattern) {\r\n result = !new RegExp(pt).test(this.value() as any);\r\n if (result) {\r\n break;\r\n }\r\n index++;\r\n }\r\n } else {\r\n result = !new RegExp(pattern as RegExp).test(this.value() as any);\r\n }\r\n return result;\r\n });\r\n requiredIsEmpty = computed(() => {\r\n return this.validatorComputed() && this.requiredComputed() && XIsEmpty(this.value());\r\n });\r\n invalidMessage = computed(() => {\r\n if (!this.validatorComputed()) return '';\r\n const message = this.messageComputed();\r\n if (Array.isArray(message)) {\r\n return message.length > this.invalidIndex() ? message[this.invalidIndex()] : '';\r\n } else {\r\n return message as string;\r\n }\r\n });\r\n invalidIndex = computed(() => {\r\n let res = 0;\r\n let index = 0;\r\n const pattern = this.patternComputed();\r\n if (!this.validatorComputed() || XIsUndefined(pattern) || XIsNull(pattern)) return 0;\r\n if (Array.isArray(pattern)) {\r\n for (const pt of pattern) {\r\n const result = !new RegExp(pt).test(this.value() as any);\r\n if (result) {\r\n res = index;\r\n break;\r\n }\r\n index++;\r\n }\r\n return res;\r\n } else {\r\n return 0;\r\n }\r\n });\r\n value = signal<any | undefined>(undefined);\r\n valueObservable = toObservable(this.value);\r\n validatorSignal = signal(false);\r\n disabledSignal = signal(false);\r\n requiredSignal = signal(false);\r\n patternSignal = signal<any>([]);\r\n messageSignal = signal<string | string[]>([]);\r\n\r\n requiredComputed = computed(() => this.requiredSignal() || this.required());\r\n disabledComputed = computed(() => this.disabledSignal() || this.disabled());\r\n validatorComputed = computed(() => this.validatorSignal() || this.validator());\r\n patternComputed = computed(() => {\r\n if (XIsEmpty(this.patternSignal())) return this.pattern();\r\n else return this.patternSignal();\r\n });\r\n messageComputed = computed(() => {\r\n if (XIsEmpty(this.messageSignal())) return this.message();\r\n else return this.messageSignal();\r\n });\r\n\r\n invalidInputValidator = signal(false);\r\n onChange!: (value: any) => void;\r\n onTouched!: () => void;\r\n writeValue(value: any): void {\r\n this.value.set(value);\r\n }\r\n registerOnChange(fn: (value: any) => void): void {\r\n this.onChange = fn;\r\n }\r\n registerOnTouched(fn: () => void): void {\r\n this.onTouched = fn;\r\n }\r\n setDisabledState(disabled: boolean) {\r\n this.disabledSignal.set(disabled);\r\n }\r\n formControlValidator() {\r\n this.validatorSignal.set(true);\r\n }\r\n };\r\n}\r\n","import { NgModule } from '@angular/core';\r\n\r\n@NgModule({\r\n imports: [],\r\n exports: []\r\n})\r\nexport class XBaseFormModule {}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ng-nest-ui-base-form.mjs","sources":["../../../../lib/ng-nest/ui/base-form/base-form.property.ts","../../../../lib/ng-nest/ui/base-form/base-form.component.ts","../../../../lib/ng-nest/ui/base-form/base-form.module.ts","../../../../lib/ng-nest/ui/base-form/ng-nest-ui-base-form.ts"],"sourcesContent":["import { Component, TemplateRef, input, model } from '@angular/core';\r\nimport {\r\n XAlign,\r\n XBoolean,\r\n XDirection,\r\n XJustify,\r\n XNumber,\r\n XProperty,\r\n XSize,\r\n XTemplate,\r\n XToBoolean,\r\n XToCssPixelValue\r\n} from '@ng-nest/ui/core';\r\n\r\n/**\r\n * 表单对象共有的参数\r\n */\r\nexport interface XFormOption {\r\n /**\r\n * 标签\r\n */\r\n label?: any;\r\n /**\r\n * 标签宽度\r\n */\r\n labelWidth?: string;\r\n /**\r\n * 标签文字对齐方式\r\n */\r\n labelAlign?: XAlign;\r\n /**\r\n * flex 布局下的子元素水平排列方式\r\n */\r\n justify?: XJustify;\r\n /**\r\n * flex 布局下的子元素垂直排列方式\r\n */\r\n align?: XAlign;\r\n /**\r\n * flex 布局下的子元素排列方向\r\n */\r\n direction?: XDirection;\r\n /**\r\n * 尺寸\r\n */\r\n size?: XSize;\r\n /**\r\n * 输入提示信息\r\n */\r\n placeholder?: string | string[];\r\n /**\r\n * 禁用\r\n */\r\n disabled?: boolean;\r\n /**\r\n * 必填\r\n */\r\n required?: boolean;\r\n /**\r\n * 正则验证规则\r\n */\r\n pattern?: RegExp | RegExp[];\r\n /**\r\n * 验证不通过提示文字\r\n */\r\n message?: string | string[];\r\n /**\r\n * 激活状态\r\n */\r\n active?: boolean;\r\n /**\r\n * 输入框点击样式\r\n */\r\n pointer?: boolean;\r\n /**\r\n * 输入验证函数\r\n */\r\n inputValidator?: (value: any) => boolean;\r\n}\r\n\r\n/**\r\n * 表单对象共有的参数\r\n */\r\n@Component({ selector: 'x-formcontrol-prop', template: '' })\r\nexport class XFormControlProp extends XProperty {\r\n /**\r\n * @zh_CN 初始启用验证,在输入值都自动开启\r\n * @en_US Initial enable validation, which is automatically enabled when the input value is\r\n */\r\n readonly validator = input<boolean, XBoolean>(false, { transform: XToBoolean });\r\n /**\r\n * @zh_CN 标签\r\n * @en_US Label\r\n */\r\n readonly label = input<XTemplate>('');\r\n /**\r\n * @zh_CN 标签宽度\r\n * @en_US Label width\r\n */\r\n readonly labelWidth = input<string, XNumber>('', { transform: XToCssPixelValue });\r\n /**\r\n * @zh_CN 标签文字对齐方式\r\n * @en_US Label text alignment method\r\n */\r\n readonly labelAlign = input<XAlign>('start');\r\n /**\r\n * @zh_CN flex 布局下的子元素水平排列方式\r\n * @en_US The level of sub-element level arrangement under flex layout\r\n */\r\n readonly justify = input<XJustify>('start');\r\n /**\r\n * @zh_CN flex 布局下的子元素垂直排列方式\r\n * @en_US sub-element vertical arrangement method under flex layout\r\n */\r\n readonly align = input<XAlign>('start');\r\n /**\r\n * @zh_CN flex 布局下的子元素排列方向\r\n * @en_US The direction of the sub-element arrangement under flex layout\r\n */\r\n readonly direction = input<XDirection>('column');\r\n /**\r\n * @zh_CN 尺寸\r\n * @en_US Size\r\n */\r\n readonly size = input<XSize>('medium');\r\n /**\r\n * @zh_CN 输入提示信息\r\n * @en_US Enter prompt information\r\n */\r\n readonly placeholder = input<string | string[]>('');\r\n /**\r\n * @zh_CN 禁用\r\n * @en_US Disabled\r\n */\r\n readonly disabled = input<boolean, XBoolean>(false, { transform: XToBoolean });\r\n /**\r\n * @zh_CN 必填\r\n * @en_US Required\r\n */\r\n readonly required = input<boolean, XBoolean>(false, { transform: XToBoolean });\r\n /**\r\n * @zh_CN 只读\r\n * @en_US Readonly\r\n */\r\n readonly readonly = input<boolean, XBoolean>(false, { transform: XToBoolean });\r\n /**\r\n * @zh_CN 值模板\r\n * @en_US Node template\r\n */\r\n readonly valueTpl = input<TemplateRef<any>>();\r\n /**\r\n * @zh_CN 值模板参数\r\n * @en_US Node template\r\n */\r\n readonly valueTplContext = input();\r\n /**\r\n * @zh_CN 前置标签\r\n * @en_US Before label\r\n */\r\n readonly before = input<XTemplate>();\r\n /**\r\n * @zh_CN 后置标签\r\n * @en_US After label\r\n */\r\n readonly after = input<XTemplate>();\r\n /**\r\n * @zh_CN 正则验证规则\r\n * @en_US Regular verification rules\r\n */\r\n readonly pattern = input<RegExp | RegExp[]>([]);\r\n /**\r\n * @zh_CN 验证不通过提示文字\r\n * @en_US Verify not pass the prompt text\r\n */\r\n readonly message = input<string | string[]>([]);\r\n /**\r\n * @zh_CN 激活状态\r\n * @en_US Activation state\r\n */\r\n readonly active = model<boolean>(false);\r\n /**\r\n * @zh_CN 输入框点击样式\r\n * @en_US Enter box click style\r\n */\r\n readonly pointer = input<boolean, XBoolean>(false, { transform: XToBoolean });\r\n /**\r\n * @zh_CN 输入验证函数\r\n * @en_US Enter the verification function\r\n */\r\n readonly inputValidator = input<(value: any) => boolean>();\r\n}\r\n","import {\r\n AbstractControl,\r\n ControlValueAccessor,\r\n NG_VALUE_ACCESSOR,\r\n ValidationErrors,\r\n ValidatorFn\r\n} from '@angular/forms';\r\nimport { ChangeDetectorRef, computed, forwardRef, inject, signal, Type } from '@angular/core';\r\nimport { XIsEmpty, XIsUndefined, XComponentConfigKey, XConfigService, XIsNull } from '@ng-nest/ui/core';\r\nimport { XFormControlProp } from './base-form.property';\r\nimport { toObservable } from '@angular/core/rxjs-interop';\r\n\r\nexport function XValueAccessor<T>(component: Type<T>) {\r\n return { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => component), multi: true };\r\n}\r\n\r\nexport function XFormInputValidator(func: (value: any) => boolean): ValidatorFn {\r\n return (control: AbstractControl): ValidationErrors | null => {\r\n const invalid = func ? !func(control.value) : null;\r\n return invalid ? { inputValidator: true } : null;\r\n };\r\n}\r\n\r\nexport function XFormControlFunction<C extends XComponentConfigKey>(configName: C) {\r\n return class XFormControlFun extends XFormControlProp implements ControlValueAccessor {\r\n config = inject(XConfigService).getConfigForComponent(configName);\r\n cdr = inject(ChangeDetectorRef);\r\n invalid = computed(() => {\r\n return (\r\n this.validatorComputed() &&\r\n ((!XIsEmpty(this.value()) && this.invalidPattern()) || this.requiredIsEmpty() || this.invalidInputValidator())\r\n );\r\n });\r\n invalidPattern = computed(() => {\r\n const pattern = this.patternComputed();\r\n if (!this.validatorComputed() || XIsUndefined(pattern) || XIsNull(pattern)) return false;\r\n let result = false;\r\n let index = 0;\r\n\r\n if (Array.isArray(pattern)) {\r\n for (const pt of pattern) {\r\n result = !new RegExp(pt).test(this.value() as any);\r\n if (result) {\r\n break;\r\n }\r\n index++;\r\n }\r\n } else {\r\n result = !new RegExp(pattern as RegExp).test(this.value() as any);\r\n }\r\n return result;\r\n });\r\n requiredIsEmpty = computed(() => {\r\n return this.validatorComputed() && this.requiredComputed() && XIsEmpty(this.value());\r\n });\r\n invalidMessage = computed(() => {\r\n if (!this.validatorComputed()) return '';\r\n const message = this.messageComputed();\r\n if (Array.isArray(message)) {\r\n return message.length > this.invalidIndex() ? message[this.invalidIndex()] : '';\r\n } else {\r\n return message as string;\r\n }\r\n });\r\n invalidIndex = computed(() => {\r\n let res = 0;\r\n let index = 0;\r\n const pattern = this.patternComputed();\r\n if (!this.validatorComputed() || XIsUndefined(pattern) || XIsNull(pattern)) return 0;\r\n if (Array.isArray(pattern)) {\r\n for (const pt of pattern) {\r\n const result = !new RegExp(pt).test(this.value() as any);\r\n if (result) {\r\n res = index;\r\n break;\r\n }\r\n index++;\r\n }\r\n return res;\r\n } else {\r\n return 0;\r\n }\r\n });\r\n value = signal<any | undefined>(undefined);\r\n valueObservable = toObservable(this.value);\r\n validatorSignal = signal(false);\r\n disabledSignal = signal(false);\r\n requiredSignal = signal(false);\r\n patternSignal = signal<any>([]);\r\n messageSignal = signal<string | string[]>([]);\r\n\r\n requiredComputed = computed(() => this.requiredSignal() || this.required());\r\n disabledComputed = computed(() => this.disabledSignal() || this.disabled());\r\n validatorComputed = computed(() => this.validatorSignal() || this.validator());\r\n patternComputed = computed(() => {\r\n if (XIsEmpty(this.patternSignal())) return this.pattern();\r\n else return this.patternSignal();\r\n });\r\n messageComputed = computed(() => {\r\n if (XIsEmpty(this.messageSignal())) return this.message();\r\n else return this.messageSignal();\r\n });\r\n\r\n invalidInputValidator = signal(false);\r\n onChange!: (value: any) => void;\r\n onTouched!: () => void;\r\n writeValue(value: any): void {\r\n this.value.set(value);\r\n }\r\n registerOnChange(fn: (value: any) => void): void {\r\n this.onChange = fn;\r\n }\r\n registerOnTouched(fn: () => void): void {\r\n this.onTouched = fn;\r\n }\r\n setDisabledState(disabled: boolean) {\r\n this.disabledSignal.set(disabled);\r\n }\r\n formControlValidator() {\r\n this.validatorSignal.set(true);\r\n }\r\n };\r\n}\r\n","import { NgModule } from '@angular/core';\r\n\r\n@NgModule({\r\n imports: [],\r\n exports: []\r\n})\r\nexport class XBaseFormModule {}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, output, Component,
|
|
2
|
+
import { input, output, Component, InjectionToken, inject, Renderer2, ChangeDetectorRef, viewChild, computed, signal, effect, ChangeDetectionStrategy, ViewEncapsulation, ElementRef, contentChildren, NgModule } from '@angular/core';
|
|
3
3
|
import { XPropertyFunction, XToBoolean, XToNumber, XIsEmpty, XIsTemplateRef, XIsString } from '@ng-nest/ui/core';
|
|
4
4
|
import { XOutletDirective } from '@ng-nest/ui/outlet';
|
|
5
5
|
import { NgClass } from '@angular/common';
|
|
6
6
|
import { XAvatarComponent } from '@ng-nest/ui/avatar';
|
|
7
7
|
import { XLoadingComponent } from '@ng-nest/ui/loading';
|
|
8
8
|
import { DomSanitizer } from '@angular/platform-browser';
|
|
9
|
-
import { Subject, fromEvent, takeUntil, isObservable } from 'rxjs';
|
|
10
9
|
import { toObservable } from '@angular/core/rxjs-interop';
|
|
10
|
+
import { isObservable, Subject, fromEvent, takeUntil } from 'rxjs';
|
|
11
11
|
import { XIconComponent } from '@ng-nest/ui/icon';
|
|
12
12
|
|
|
13
13
|
/**
|
|
@@ -153,128 +153,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
153
153
|
args: [{ selector: `${XBubblesPrefix}-property`, template: '' }]
|
|
154
154
|
}], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], scrollChange: [{ type: i0.Output, args: ["scrollChange"] }] } });
|
|
155
155
|
|
|
156
|
-
|
|
157
|
-
constructor() {
|
|
158
|
-
super(...arguments);
|
|
159
|
-
this.elementRef = inject(ElementRef);
|
|
160
|
-
this.renderer = inject(Renderer2);
|
|
161
|
-
this.parentScrollElement = null;
|
|
162
|
-
this.isFollowing = true;
|
|
163
|
-
this.removeScrollListener = null;
|
|
164
|
-
this.contentMutationObserver = null;
|
|
165
|
-
this.typingObserver = null;
|
|
166
|
-
this.$destroy = new Subject();
|
|
167
|
-
this.bubbles = contentChildren(XBubbleComponent, ...(ngDevMode ? [{ debugName: "bubbles" }] : []));
|
|
168
|
-
}
|
|
169
|
-
ngAfterViewInit() {
|
|
170
|
-
this.stepScroll();
|
|
171
|
-
this.observeContentChanges();
|
|
172
|
-
}
|
|
173
|
-
ngDoCheck() {
|
|
174
|
-
const bubbles = this.bubbles();
|
|
175
|
-
if (bubbles.length <= 0)
|
|
176
|
-
return;
|
|
177
|
-
const lastBubble = bubbles[bubbles.length - 1];
|
|
178
|
-
if (lastBubble &&
|
|
179
|
-
lastBubble.typing() &&
|
|
180
|
-
(lastBubble.pendingContent().length > 0 || lastBubble.reasoningPendingContent().length > 0)) {
|
|
181
|
-
if (!this.typingObserver) {
|
|
182
|
-
this.startTypingObserver(lastBubble);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
else {
|
|
186
|
-
if (this.typingObserver) {
|
|
187
|
-
this.stopTypingObserver();
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
ngOnDestroy() {
|
|
192
|
-
this.removeScrollListener?.unsubscribe();
|
|
193
|
-
this.contentMutationObserver?.disconnect();
|
|
194
|
-
this.stopTypingObserver();
|
|
195
|
-
this.$destroy.next();
|
|
196
|
-
this.$destroy.complete();
|
|
197
|
-
}
|
|
198
|
-
stepScroll() {
|
|
199
|
-
const newScroll = this.getParentScrollElement(this.elementRef.nativeElement);
|
|
200
|
-
if (this.parentScrollElement && newScroll === this.parentScrollElement)
|
|
201
|
-
return;
|
|
202
|
-
this.parentScrollElement = newScroll;
|
|
203
|
-
if (this.parentScrollElement) {
|
|
204
|
-
this.removeScrollListener?.unsubscribe();
|
|
205
|
-
this.removeScrollListener = fromEvent(this.parentScrollElement, 'scroll')
|
|
206
|
-
.pipe(takeUntil(this.$destroy))
|
|
207
|
-
.subscribe((event) => {
|
|
208
|
-
const atBottom = this.parentScrollElement.scrollHeight - this.parentScrollElement.scrollTop ===
|
|
209
|
-
this.parentScrollElement.clientHeight;
|
|
210
|
-
if (!atBottom) {
|
|
211
|
-
this.isFollowing = false;
|
|
212
|
-
}
|
|
213
|
-
else {
|
|
214
|
-
this.isFollowing = true;
|
|
215
|
-
}
|
|
216
|
-
this.scrollChange.emit(event);
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
getParentScrollElement(element) {
|
|
221
|
-
let parent = this.renderer.parentNode(element);
|
|
222
|
-
while (parent && parent.nodeType === 1) {
|
|
223
|
-
const overflowY = getComputedStyle(parent).overflowY;
|
|
224
|
-
if (overflowY === 'auto' || overflowY === 'scroll') {
|
|
225
|
-
return parent;
|
|
226
|
-
}
|
|
227
|
-
parent = this.renderer.parentNode(parent);
|
|
228
|
-
}
|
|
229
|
-
return null;
|
|
230
|
-
}
|
|
231
|
-
observeContentChanges() {
|
|
232
|
-
this.contentMutationObserver = new MutationObserver(() => {
|
|
233
|
-
this.isFollowing = true;
|
|
234
|
-
this.scrollToBottom();
|
|
235
|
-
});
|
|
236
|
-
this.contentMutationObserver.observe(this.elementRef.nativeElement, { childList: true });
|
|
237
|
-
}
|
|
238
|
-
startTypingObserver(bubble) {
|
|
239
|
-
const bubbleContent = bubble.wrapperRef()?.nativeElement;
|
|
240
|
-
if (bubbleContent) {
|
|
241
|
-
this.typingObserver = new MutationObserver(() => {
|
|
242
|
-
if (this.isFollowing) {
|
|
243
|
-
this.scrollToBottom();
|
|
244
|
-
}
|
|
245
|
-
});
|
|
246
|
-
this.typingObserver.observe(bubbleContent, {
|
|
247
|
-
childList: true,
|
|
248
|
-
subtree: true,
|
|
249
|
-
characterData: true
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
stopTypingObserver() {
|
|
254
|
-
if (this.typingObserver) {
|
|
255
|
-
this.typingObserver.disconnect();
|
|
256
|
-
this.typingObserver = null;
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
scrollToBottom() {
|
|
260
|
-
this.stepScroll();
|
|
261
|
-
if (this.parentScrollElement) {
|
|
262
|
-
this.parentScrollElement.scrollTop = this.parentScrollElement.scrollHeight;
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
scrollToTop() {
|
|
266
|
-
this.stepScroll();
|
|
267
|
-
if (this.parentScrollElement) {
|
|
268
|
-
this.parentScrollElement.scrollTop = 0;
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: XBubblesComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
272
|
-
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.0.6", type: XBubblesComponent, isStandalone: true, selector: "x-bubbles", queries: [{ propertyName: "bubbles", predicate: XBubbleComponent, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<ng-content></ng-content>\r\n", styles: ["x-bubbles{margin:0;padding:0}x-bubbles{display:flex;flex-direction:column;gap:1rem}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
273
|
-
}
|
|
274
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: XBubblesComponent, decorators: [{
|
|
275
|
-
type: Component,
|
|
276
|
-
args: [{ selector: 'x-bubbles', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [], template: "<ng-content></ng-content>\r\n", styles: ["x-bubbles{margin:0;padding:0}x-bubbles{display:flex;flex-direction:column;gap:1rem}\n"] }]
|
|
277
|
-
}], propDecorators: { bubbles: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => XBubbleComponent), { isSignal: true }] }] } });
|
|
156
|
+
const X_BUBBLES_CONTEXT = new InjectionToken('X_BUBBLES_CONTEXT');
|
|
278
157
|
|
|
279
158
|
class XBubbleComponent extends XBubbleProperty {
|
|
280
159
|
constructor() {
|
|
@@ -282,7 +161,7 @@ class XBubbleComponent extends XBubbleProperty {
|
|
|
282
161
|
this.sanitizer = inject(DomSanitizer);
|
|
283
162
|
this.renderer2 = inject(Renderer2);
|
|
284
163
|
this.cdr = inject(ChangeDetectorRef);
|
|
285
|
-
this.bubbles = inject(
|
|
164
|
+
this.bubbles = inject(X_BUBBLES_CONTEXT, { optional: true });
|
|
286
165
|
this.wrapperRef = viewChild('wrapperRef', ...(ngDevMode ? [{ debugName: "wrapperRef" }] : []));
|
|
287
166
|
this.classMap = computed(() => ({
|
|
288
167
|
[`${XBubblePrefix}-${this.variantSignal()}`]: !XIsEmpty(this.variantSignal()),
|
|
@@ -303,10 +182,10 @@ class XBubbleComponent extends XBubbleProperty {
|
|
|
303
182
|
this.typingInterval = null;
|
|
304
183
|
this.renderedContent = signal('', ...(ngDevMode ? [{ debugName: "renderedContent" }] : []));
|
|
305
184
|
this.sizeSignal = computed(() => {
|
|
306
|
-
return this.bubbles?.size() || this.size();
|
|
185
|
+
return (this.bubbles?.size() || this.size());
|
|
307
186
|
}, ...(ngDevMode ? [{ debugName: "sizeSignal" }] : []));
|
|
308
187
|
this.variantSignal = computed(() => {
|
|
309
|
-
return this.bubbles?.variant() || this.variant();
|
|
188
|
+
return (this.bubbles?.variant() || this.variant());
|
|
310
189
|
}, ...(ngDevMode ? [{ debugName: "variantSignal" }] : []));
|
|
311
190
|
this.isTemplate = computed(() => {
|
|
312
191
|
return XIsTemplateRef(this.content());
|
|
@@ -459,13 +338,146 @@ class XBubbleComponent extends XBubbleProperty {
|
|
|
459
338
|
this.stopTyping();
|
|
460
339
|
}
|
|
461
340
|
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: XBubbleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
462
|
-
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: XBubbleComponent, isStandalone: true, selector: "x-bubble", viewQueries: [{ propertyName: "wrapperRef", first: true, predicate: ["wrapperRef"], descendants: true, isSignal: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"x-bubble\" [ngClass]=\"classMap()\">\r\n @if (!!avatar()) {\r\n <div class=\"x-bubble-avatar\" [class.x-bubble-avatar-hidden]=\"avatar()?.hidden\">\r\n <x-avatar\r\n [icon]=\"avatar()?.icon!\"\r\n [label]=\"avatar()?.label!\"\r\n [src]=\"avatar()?.src!\"\r\n [size]=\"avatar()?.size ??
|
|
341
|
+
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: XBubbleComponent, isStandalone: true, selector: "x-bubble", viewQueries: [{ propertyName: "wrapperRef", first: true, predicate: ["wrapperRef"], descendants: true, isSignal: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"x-bubble\" [ngClass]=\"classMap()\">\r\n @if (!!avatar()) {\r\n <div class=\"x-bubble-avatar\" [class.x-bubble-avatar-hidden]=\"avatar()?.hidden\">\r\n <x-avatar\r\n [icon]=\"avatar()?.icon!\"\r\n [label]=\"avatar()?.label!\"\r\n [src]=\"avatar()?.src!\"\r\n [size]=\"avatar()?.size ?? sizeSignal()\"\r\n [gap]=\"avatar()?.gap ?? '0.25rem'\"\r\n [fit]=\"avatar()?.fit ?? 'cover'\"\r\n [backgroundColor]=\"avatar()?.backgroundColor ?? '#999999'\"\r\n [color]=\"avatar()?.color ?? '#FFFFFF'\"\r\n [shape]=\"avatar()?.shape ?? 'circle'\"\r\n ></x-avatar>\r\n </div>\r\n }\r\n <div #wrapperRef class=\"x-bubble-wrapper\">\r\n @if (loading()) {\r\n <div class=\"x-bubble-content\" [x-loading]=\"true\" [size]=\"'small'\" inline></div>\r\n } @else {\r\n @if (header()) {\r\n <div class=\"x-bubble-header\">\r\n <ng-container *xOutlet=\"header()\">{{ header() }}</ng-container>\r\n </div>\r\n }\r\n\r\n @if (isReasoningString()) {\r\n <div class=\"x-bubble-reasoning\">\r\n <ng-container *xOutlet=\"reasoningHeaderTpl\"></ng-container>\r\n @if (reasoningToggle()) {\r\n <div class=\"x-bubble-reasoning-content\" #reasoningContentRef [innerHTML]=\"reasoningRenderedContent()\"></div>\r\n }\r\n </div>\r\n } @else if (isReasoningTemplate()) {\r\n <div class=\"x-bubble-reasoning\">\r\n <ng-container *xOutlet=\"reasoningHeaderTpl\"></ng-container>\r\n @if (reasoningToggle()) {\r\n <div class=\"x-bubble-reasoning-content\" #reasoningContentRef>\r\n <ng-container *xOutlet=\"reasoningContent()\"></ng-container>\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <ng-template #reasoningHeaderTpl>\r\n <div class=\"x-bubble-reasoning-header\" (click)=\"onReasoningToggle()\">\r\n <x-icon\r\n class=\"x-bubble-reasoning-toggle\"\r\n [type]=\"reasoningToggle() ? 'fto-chevron-down' : 'fto-chevron-right'\"\r\n ></x-icon>\r\n <span>{{ reasoningTitle() }}</span>\r\n </div>\r\n </ng-template>\r\n\r\n @if (isString()) {\r\n <div class=\"x-bubble-content\" #contentRef [innerHTML]=\"renderedContent()\"></div>\r\n } @else if (isTemplate()) {\r\n <div class=\"x-bubble-content\" #contentRef>\r\n <ng-container *xOutlet=\"content()\"></ng-container>\r\n </div>\r\n }\r\n\r\n @if (footer()) {\r\n <div class=\"x-bubble-footer\">\r\n <ng-container *xOutlet=\"footer()\">{{ footer() }}</ng-container>\r\n </div>\r\n }\r\n }\r\n </div>\r\n</div>\r\n", styles: [".x-bubble{margin:0;padding:0}.x-bubble{display:flex}.x-bubble-wrapper{flex:auto;display:flex;flex-direction:column;align-items:flex-start;min-width:0;max-width:100%}.x-bubble-reasoning{background-color:var(--x-background-a100);color:var(--x-text-400);position:relative;box-sizing:border-box;min-width:0;max-width:100%;font-size:var(--x-font-size-small);border-radius:var(--x-border-radius);word-break:break-word;margin-bottom:1rem}.x-bubble-reasoning-header{padding:.5rem 1rem .5rem .45rem;display:flex;align-items:center;gap:.5rem;cursor:pointer}.x-bubble-reasoning-toggle{font-size:var(--x-font-size-large)}.x-bubble-reasoning-content{position:relative;padding:0rem 1rem 0rem 2rem;margin-bottom:1rem}.x-bubble-reasoning-content:before{position:absolute;top:0;left:1rem;content:\" \";height:100%;border-left:var(--x-border-width) var(--x-border-style) var(--x-border)}.x-bubble-content{position:relative;box-sizing:border-box;min-width:0;max-width:100%;color:var(--x-text);font-size:var(--x-font-size);border-radius:var(--x-border-radius);word-break:break-word}.x-bubble-outlined .x-bubble-content{border:var(--x-border-width) var(--x-border-style) var(--x-border)}.x-bubble-filled .x-bubble-content{background-color:var(--x-background-a200)}.x-bubble-shadow .x-bubble-content{box-shadow:var(--x-box-shadow)}.x-bubble-end{flex-direction:row-reverse}.x-bubble-end .x-bubble-wrapper{align-items:flex-end}.x-bubble-header{margin-bottom:.25rem}.x-bubble-footer{margin-top:.5rem}.x-bubble-cursor.x-bubble-typing .x-bubble-content:after{content:\"\";display:inline-block;width:.0625rem;height:1.1em;margin-left:.0625rem;background-color:currentColor;vertical-align:middle;animation:x-bubble-blink 1s infinite}.x-bubble-cursor:not(.x-bubble-typing) .x-bubble-content:after{display:none}.x-bubble-avatar-hidden{visibility:hidden}@keyframes x-bubble-blink{0%{opacity:1}50%{opacity:0}to{opacity:1}}.x-bubble.x-big{column-gap:var(--x-padding-big)}.x-bubble.x-big .x-bubble-content{padding:calc(var(--x-padding-big) - .25rem) var(--x-padding-big);line-height:calc(var(--x-height-big) - 1rem);min-height:calc(var(--x-padding-big) * 2 + var(--x-height-big) - 1.5rem)}.x-bubble.x-large{column-gap:var(--x-padding-large)}.x-bubble.x-large .x-bubble-content{padding:calc(var(--x-padding-large) - .25rem) var(--x-padding-large);line-height:calc(var(--x-height-large) - 1rem);min-height:calc(var(--x-padding-large) * 2 + var(--x-height-large) - 1.5rem)}.x-bubble.x-medium{column-gap:var(--x-padding-medium)}.x-bubble.x-medium .x-bubble-content{padding:calc(var(--x-padding-medium) - .25rem) var(--x-padding-medium);line-height:calc(var(--x-height-medium) - 1rem);min-height:calc(var(--x-padding-medium) * 2 + var(--x-height-medium) - 1.5rem)}.x-bubble.x-small{column-gap:var(--x-padding-small)}.x-bubble.x-small .x-bubble-content{padding:calc(var(--x-padding-small) - .25rem) var(--x-padding-small);line-height:calc(var(--x-height-small) - 1rem);min-height:calc(var(--x-padding-small) * 2 + var(--x-height-small) - 1.5rem)}.x-bubble.x-mini{column-gap:var(--x-padding-mini)}.x-bubble.x-mini .x-bubble-content{padding:calc(var(--x-padding-mini) - .25rem) var(--x-padding-mini);line-height:calc(var(--x-height-mini) - 1rem);min-height:calc(var(--x-padding-mini) * 2 + var(--x-height-mini) - 1.5rem)}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: XOutletDirective, selector: "[xOutlet]", inputs: ["xOutletContext", "xOutlet"] }, { kind: "component", type: XAvatarComponent, selector: "x-avatar" }, { kind: "component", type: XIconComponent, selector: "x-icon" }, { kind: "component", type: XLoadingComponent, selector: "x-loading, [x-loading]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
463
342
|
}
|
|
464
343
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: XBubbleComponent, decorators: [{
|
|
465
344
|
type: Component,
|
|
466
|
-
args: [{ selector: 'x-bubble', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgClass, XOutletDirective, XAvatarComponent, XIconComponent, XLoadingComponent], template: "<div class=\"x-bubble\" [ngClass]=\"classMap()\">\r\n @if (!!avatar()) {\r\n <div class=\"x-bubble-avatar\" [class.x-bubble-avatar-hidden]=\"avatar()?.hidden\">\r\n <x-avatar\r\n [icon]=\"avatar()?.icon!\"\r\n [label]=\"avatar()?.label!\"\r\n [src]=\"avatar()?.src!\"\r\n [size]=\"avatar()?.size ??
|
|
345
|
+
args: [{ selector: 'x-bubble', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgClass, XOutletDirective, XAvatarComponent, XIconComponent, XLoadingComponent], template: "<div class=\"x-bubble\" [ngClass]=\"classMap()\">\r\n @if (!!avatar()) {\r\n <div class=\"x-bubble-avatar\" [class.x-bubble-avatar-hidden]=\"avatar()?.hidden\">\r\n <x-avatar\r\n [icon]=\"avatar()?.icon!\"\r\n [label]=\"avatar()?.label!\"\r\n [src]=\"avatar()?.src!\"\r\n [size]=\"avatar()?.size ?? sizeSignal()\"\r\n [gap]=\"avatar()?.gap ?? '0.25rem'\"\r\n [fit]=\"avatar()?.fit ?? 'cover'\"\r\n [backgroundColor]=\"avatar()?.backgroundColor ?? '#999999'\"\r\n [color]=\"avatar()?.color ?? '#FFFFFF'\"\r\n [shape]=\"avatar()?.shape ?? 'circle'\"\r\n ></x-avatar>\r\n </div>\r\n }\r\n <div #wrapperRef class=\"x-bubble-wrapper\">\r\n @if (loading()) {\r\n <div class=\"x-bubble-content\" [x-loading]=\"true\" [size]=\"'small'\" inline></div>\r\n } @else {\r\n @if (header()) {\r\n <div class=\"x-bubble-header\">\r\n <ng-container *xOutlet=\"header()\">{{ header() }}</ng-container>\r\n </div>\r\n }\r\n\r\n @if (isReasoningString()) {\r\n <div class=\"x-bubble-reasoning\">\r\n <ng-container *xOutlet=\"reasoningHeaderTpl\"></ng-container>\r\n @if (reasoningToggle()) {\r\n <div class=\"x-bubble-reasoning-content\" #reasoningContentRef [innerHTML]=\"reasoningRenderedContent()\"></div>\r\n }\r\n </div>\r\n } @else if (isReasoningTemplate()) {\r\n <div class=\"x-bubble-reasoning\">\r\n <ng-container *xOutlet=\"reasoningHeaderTpl\"></ng-container>\r\n @if (reasoningToggle()) {\r\n <div class=\"x-bubble-reasoning-content\" #reasoningContentRef>\r\n <ng-container *xOutlet=\"reasoningContent()\"></ng-container>\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <ng-template #reasoningHeaderTpl>\r\n <div class=\"x-bubble-reasoning-header\" (click)=\"onReasoningToggle()\">\r\n <x-icon\r\n class=\"x-bubble-reasoning-toggle\"\r\n [type]=\"reasoningToggle() ? 'fto-chevron-down' : 'fto-chevron-right'\"\r\n ></x-icon>\r\n <span>{{ reasoningTitle() }}</span>\r\n </div>\r\n </ng-template>\r\n\r\n @if (isString()) {\r\n <div class=\"x-bubble-content\" #contentRef [innerHTML]=\"renderedContent()\"></div>\r\n } @else if (isTemplate()) {\r\n <div class=\"x-bubble-content\" #contentRef>\r\n <ng-container *xOutlet=\"content()\"></ng-container>\r\n </div>\r\n }\r\n\r\n @if (footer()) {\r\n <div class=\"x-bubble-footer\">\r\n <ng-container *xOutlet=\"footer()\">{{ footer() }}</ng-container>\r\n </div>\r\n }\r\n }\r\n </div>\r\n</div>\r\n", styles: [".x-bubble{margin:0;padding:0}.x-bubble{display:flex}.x-bubble-wrapper{flex:auto;display:flex;flex-direction:column;align-items:flex-start;min-width:0;max-width:100%}.x-bubble-reasoning{background-color:var(--x-background-a100);color:var(--x-text-400);position:relative;box-sizing:border-box;min-width:0;max-width:100%;font-size:var(--x-font-size-small);border-radius:var(--x-border-radius);word-break:break-word;margin-bottom:1rem}.x-bubble-reasoning-header{padding:.5rem 1rem .5rem .45rem;display:flex;align-items:center;gap:.5rem;cursor:pointer}.x-bubble-reasoning-toggle{font-size:var(--x-font-size-large)}.x-bubble-reasoning-content{position:relative;padding:0rem 1rem 0rem 2rem;margin-bottom:1rem}.x-bubble-reasoning-content:before{position:absolute;top:0;left:1rem;content:\" \";height:100%;border-left:var(--x-border-width) var(--x-border-style) var(--x-border)}.x-bubble-content{position:relative;box-sizing:border-box;min-width:0;max-width:100%;color:var(--x-text);font-size:var(--x-font-size);border-radius:var(--x-border-radius);word-break:break-word}.x-bubble-outlined .x-bubble-content{border:var(--x-border-width) var(--x-border-style) var(--x-border)}.x-bubble-filled .x-bubble-content{background-color:var(--x-background-a200)}.x-bubble-shadow .x-bubble-content{box-shadow:var(--x-box-shadow)}.x-bubble-end{flex-direction:row-reverse}.x-bubble-end .x-bubble-wrapper{align-items:flex-end}.x-bubble-header{margin-bottom:.25rem}.x-bubble-footer{margin-top:.5rem}.x-bubble-cursor.x-bubble-typing .x-bubble-content:after{content:\"\";display:inline-block;width:.0625rem;height:1.1em;margin-left:.0625rem;background-color:currentColor;vertical-align:middle;animation:x-bubble-blink 1s infinite}.x-bubble-cursor:not(.x-bubble-typing) .x-bubble-content:after{display:none}.x-bubble-avatar-hidden{visibility:hidden}@keyframes x-bubble-blink{0%{opacity:1}50%{opacity:0}to{opacity:1}}.x-bubble.x-big{column-gap:var(--x-padding-big)}.x-bubble.x-big .x-bubble-content{padding:calc(var(--x-padding-big) - .25rem) var(--x-padding-big);line-height:calc(var(--x-height-big) - 1rem);min-height:calc(var(--x-padding-big) * 2 + var(--x-height-big) - 1.5rem)}.x-bubble.x-large{column-gap:var(--x-padding-large)}.x-bubble.x-large .x-bubble-content{padding:calc(var(--x-padding-large) - .25rem) var(--x-padding-large);line-height:calc(var(--x-height-large) - 1rem);min-height:calc(var(--x-padding-large) * 2 + var(--x-height-large) - 1.5rem)}.x-bubble.x-medium{column-gap:var(--x-padding-medium)}.x-bubble.x-medium .x-bubble-content{padding:calc(var(--x-padding-medium) - .25rem) var(--x-padding-medium);line-height:calc(var(--x-height-medium) - 1rem);min-height:calc(var(--x-padding-medium) * 2 + var(--x-height-medium) - 1.5rem)}.x-bubble.x-small{column-gap:var(--x-padding-small)}.x-bubble.x-small .x-bubble-content{padding:calc(var(--x-padding-small) - .25rem) var(--x-padding-small);line-height:calc(var(--x-height-small) - 1rem);min-height:calc(var(--x-padding-small) * 2 + var(--x-height-small) - 1.5rem)}.x-bubble.x-mini{column-gap:var(--x-padding-mini)}.x-bubble.x-mini .x-bubble-content{padding:calc(var(--x-padding-mini) - .25rem) var(--x-padding-mini);line-height:calc(var(--x-height-mini) - 1rem);min-height:calc(var(--x-padding-mini) * 2 + var(--x-height-mini) - 1.5rem)}\n"] }]
|
|
467
346
|
}], ctorParameters: () => [], propDecorators: { wrapperRef: [{ type: i0.ViewChild, args: ['wrapperRef', { isSignal: true }] }] } });
|
|
468
347
|
|
|
348
|
+
class XBubblesComponent extends XBubblesProperty {
|
|
349
|
+
constructor() {
|
|
350
|
+
super(...arguments);
|
|
351
|
+
this.elementRef = inject(ElementRef);
|
|
352
|
+
this.renderer = inject(Renderer2);
|
|
353
|
+
this.parentScrollElement = null;
|
|
354
|
+
this.isFollowing = true;
|
|
355
|
+
this.removeScrollListener = null;
|
|
356
|
+
this.contentMutationObserver = null;
|
|
357
|
+
this.typingObserver = null;
|
|
358
|
+
this.$destroy = new Subject();
|
|
359
|
+
this.bubbles = contentChildren(XBubbleComponent, ...(ngDevMode ? [{ debugName: "bubbles" }] : []));
|
|
360
|
+
}
|
|
361
|
+
ngAfterViewInit() {
|
|
362
|
+
this.stepScroll();
|
|
363
|
+
this.observeContentChanges();
|
|
364
|
+
}
|
|
365
|
+
ngDoCheck() {
|
|
366
|
+
const bubbles = this.bubbles();
|
|
367
|
+
if (bubbles.length <= 0)
|
|
368
|
+
return;
|
|
369
|
+
const lastBubble = bubbles[bubbles.length - 1];
|
|
370
|
+
if (lastBubble &&
|
|
371
|
+
lastBubble.typing() &&
|
|
372
|
+
(lastBubble.pendingContent().length > 0 || lastBubble.reasoningPendingContent().length > 0)) {
|
|
373
|
+
if (!this.typingObserver) {
|
|
374
|
+
this.startTypingObserver(lastBubble);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
if (this.typingObserver) {
|
|
379
|
+
this.stopTypingObserver();
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
ngOnDestroy() {
|
|
384
|
+
this.removeScrollListener?.unsubscribe();
|
|
385
|
+
this.contentMutationObserver?.disconnect();
|
|
386
|
+
this.stopTypingObserver();
|
|
387
|
+
this.$destroy.next();
|
|
388
|
+
this.$destroy.complete();
|
|
389
|
+
}
|
|
390
|
+
stepScroll() {
|
|
391
|
+
const newScroll = this.getParentScrollElement(this.elementRef.nativeElement);
|
|
392
|
+
if (this.parentScrollElement && newScroll === this.parentScrollElement)
|
|
393
|
+
return;
|
|
394
|
+
this.parentScrollElement = newScroll;
|
|
395
|
+
if (this.parentScrollElement) {
|
|
396
|
+
this.removeScrollListener?.unsubscribe();
|
|
397
|
+
this.removeScrollListener = fromEvent(this.parentScrollElement, 'scroll')
|
|
398
|
+
.pipe(takeUntil(this.$destroy))
|
|
399
|
+
.subscribe((event) => {
|
|
400
|
+
const atBottom = this.parentScrollElement.scrollHeight - this.parentScrollElement.scrollTop ===
|
|
401
|
+
this.parentScrollElement.clientHeight;
|
|
402
|
+
if (!atBottom) {
|
|
403
|
+
this.isFollowing = false;
|
|
404
|
+
}
|
|
405
|
+
else {
|
|
406
|
+
this.isFollowing = true;
|
|
407
|
+
}
|
|
408
|
+
this.scrollChange.emit(event);
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
getParentScrollElement(element) {
|
|
413
|
+
let parent = this.renderer.parentNode(element);
|
|
414
|
+
while (parent && parent.nodeType === 1) {
|
|
415
|
+
const overflowY = getComputedStyle(parent).overflowY;
|
|
416
|
+
if (overflowY === 'auto' || overflowY === 'scroll') {
|
|
417
|
+
return parent;
|
|
418
|
+
}
|
|
419
|
+
parent = this.renderer.parentNode(parent);
|
|
420
|
+
}
|
|
421
|
+
return null;
|
|
422
|
+
}
|
|
423
|
+
observeContentChanges() {
|
|
424
|
+
this.contentMutationObserver = new MutationObserver(() => {
|
|
425
|
+
this.isFollowing = true;
|
|
426
|
+
this.scrollToBottom();
|
|
427
|
+
});
|
|
428
|
+
this.contentMutationObserver.observe(this.elementRef.nativeElement, { childList: true });
|
|
429
|
+
}
|
|
430
|
+
startTypingObserver(bubble) {
|
|
431
|
+
const bubbleContent = bubble.wrapperRef()?.nativeElement;
|
|
432
|
+
if (bubbleContent) {
|
|
433
|
+
this.typingObserver = new MutationObserver(() => {
|
|
434
|
+
if (this.isFollowing) {
|
|
435
|
+
this.scrollToBottom();
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
this.typingObserver.observe(bubbleContent, {
|
|
439
|
+
childList: true,
|
|
440
|
+
subtree: true,
|
|
441
|
+
characterData: true
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
stopTypingObserver() {
|
|
446
|
+
if (this.typingObserver) {
|
|
447
|
+
this.typingObserver.disconnect();
|
|
448
|
+
this.typingObserver = null;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
scrollToBottom() {
|
|
452
|
+
this.stepScroll();
|
|
453
|
+
if (this.parentScrollElement) {
|
|
454
|
+
this.parentScrollElement.scrollTop = this.parentScrollElement.scrollHeight;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
scrollToTop() {
|
|
458
|
+
this.stepScroll();
|
|
459
|
+
if (this.parentScrollElement) {
|
|
460
|
+
this.parentScrollElement.scrollTop = 0;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: XBubblesComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
464
|
+
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.0.6", type: XBubblesComponent, isStandalone: true, selector: "x-bubbles", providers: [
|
|
465
|
+
{
|
|
466
|
+
provide: X_BUBBLES_CONTEXT,
|
|
467
|
+
useExisting: XBubblesComponent
|
|
468
|
+
}
|
|
469
|
+
], queries: [{ propertyName: "bubbles", predicate: XBubbleComponent, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<ng-content></ng-content>\r\n", styles: ["x-bubbles{margin:0;padding:0}x-bubbles{display:flex;flex-direction:column;gap:1rem}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
470
|
+
}
|
|
471
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: XBubblesComponent, decorators: [{
|
|
472
|
+
type: Component,
|
|
473
|
+
args: [{ selector: 'x-bubbles', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [], providers: [
|
|
474
|
+
{
|
|
475
|
+
provide: X_BUBBLES_CONTEXT,
|
|
476
|
+
useExisting: XBubblesComponent
|
|
477
|
+
}
|
|
478
|
+
], template: "<ng-content></ng-content>\r\n", styles: ["x-bubbles{margin:0;padding:0}x-bubbles{display:flex;flex-direction:column;gap:1rem}\n"] }]
|
|
479
|
+
}], propDecorators: { bubbles: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => XBubbleComponent), { isSignal: true }] }] } });
|
|
480
|
+
|
|
469
481
|
class XBubbleModule {
|
|
470
482
|
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: XBubbleModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
471
483
|
/** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.0.6", ngImport: i0, type: XBubbleModule, imports: [XBubbleComponent, XBubblesComponent], exports: [XBubbleComponent, XBubblesComponent] }); }
|