diff --git a/src/LiveWeb-Core/LWCustomElement.class.st b/src/LiveWeb-Core/LWCustomElement.class.st index ceaff71..0c94438 100644 --- a/src/LiveWeb-Core/LWCustomElement.class.st +++ b/src/LiveWeb-Core/LWCustomElement.class.st @@ -33,6 +33,11 @@ LWCustomElement >> add: aComponent beforeIndex: idx [ ^ c ] +{ #category : #accessing } +LWCustomElement >> addClassName: aClassName [ + ^self attrAt: 'class' update: [ :old | (' ' join: { old. aClassName })] +] + { #category : #accessing } LWCustomElement >> attrAt: name [ ^ attrs at: name @@ -66,6 +71,11 @@ LWCustomElement >> children [ ] ] +{ #category : #accessing } +LWCustomElement >> className: aClassName [ + ^self attrAt: 'class' update: [ aClassName ] +] + { #category : #initialization } LWCustomElement >> initialize [ super initialize. @@ -97,7 +107,7 @@ LWCustomElement >> renderAttrs: h [ << ' '; << name; << '="'; - << (h escapeAttributeValue: val asString); + << (h escapeHtml: val asString); << '"' ] ] "skip boolean attributes that are false" ] ] ] diff --git a/src/LiveWeb-Core/LWCustomElementSlot.class.st b/src/LiveWeb-Core/LWCustomElementSlot.class.st new file mode 100644 index 0000000..91c8979 --- /dev/null +++ b/src/LiveWeb-Core/LWCustomElementSlot.class.st @@ -0,0 +1,20 @@ +Class { + #name : #LWCustomElementSlot, + #superclass : #LWSingleContainer, + #instVars : [ + 'slot' + ], + #category : #'LiveWeb-Core' +} + +{ #category : #initialization } +LWCustomElementSlot >> initialize [ + super initialize. + containerElement := #div. +] + +{ #category : #accessing } +LWCustomElementSlot >> slot: slotName [ + containerAttributes := { #slot -> slotName }. + +] diff --git a/src/LiveWeb-Developer/LWDevClassView.class.st b/src/LiveWeb-Developer/LWDevClassView.class.st index 48beae8..93c7db6 100644 --- a/src/LiveWeb-Developer/LWDevClassView.class.st +++ b/src/LiveWeb-Developer/LWDevClassView.class.st @@ -1,15 +1,22 @@ Class { #name : #LWDevClassView, - #superclass : #LWBulmaComponent, + #superclass : #LWComponent, #instVars : [ 'classDef', 'methods', 'cls', - 'export' + 'export', + 'slot' ], #category : #'LiveWeb-Developer' } +{ #category : #accessing } +LWDevClassView >> children [ + ^ ReadStream on: { export. classDef. methods } + +] + { #category : #accessing } LWDevClassView >> cls: aClass [ cls := aClass. @@ -56,18 +63,36 @@ LWDevClassView >> initialize [ methods := LWSingleContainer new. ] +{ #category : #accessing } +LWDevClassView >> render: h [ + h div: {#slot->slot. #style-> 'display: inline-flex; flex-direction: column; height: 95vh; overflow-y: scroll'} + with: [ + export render: h. + classDef render: h. + methods render: h + ] +] + { #category : #rendering } LWDevClassView >> renderClassDefOn: h [ h div: { #class -> 'section' } with: [ - cls ifNil: [ h div: 'No class selected'. ^ nil ]. - h div: [ - h strong: 'Name: '; span: cls name - "FIXME: show slots, superclass and so on" - ] -] + cls + ifNil: [ h div: 'No class selected'. ] + ifNotNil: [ + h div: [ + h strong: 'Name: '; span: cls name + "FIXME: show slots, superclass and so on" + ] + ] + ] ] +{ #category : #accessing } +LWDevClassView >> slot: slotName [ + slot := slotName +] + { #category : #accessing } LWDevClassView >> view: view [ ^view flexCol diff --git a/src/LiveWeb-Developer/LWDevListing.class.st b/src/LiveWeb-Developer/LWDevListing.class.st index 4891980..4ac6c97 100644 --- a/src/LiveWeb-Developer/LWDevListing.class.st +++ b/src/LiveWeb-Developer/LWDevListing.class.st @@ -4,7 +4,8 @@ Class { #instVars : [ 'filter', 'export', - 'listing' + 'listing', + 'slot' ], #category : #'LiveWeb-Developer' } @@ -72,8 +73,7 @@ LWDevListing >> renderListingOn: h [ { #category : #rendering } LWDevListing >> renderOn: h [ - - h div: { #style -> 'height: 95vh;' } with: [ + h div: { #style -> 'display: inline-block; height: 95vh;'. #slot-> slot } with: [ export render: h. h input: { (#placeholder -> 'filter...'). @@ -98,3 +98,8 @@ LWDevListing >> select: value [ LWDevListing >> selectJSName [ ^ 'select{1}' format: { ('' join: self class name splitCamelCase allButFirst) } ] + +{ #category : #accessing } +LWDevListing >> slot: slotName [ + slot := slotName +] diff --git a/src/LiveWeb-Developer/LWDevMain.class.st b/src/LiveWeb-Developer/LWDevMain.class.st index 5a9b8a4..909c11b 100644 --- a/src/LiveWeb-Developer/LWDevMain.class.st +++ b/src/LiveWeb-Developer/LWDevMain.class.st @@ -1,9 +1,54 @@ Class { #name : #LWDevMain, - #superclass : #LWBulmaComponent, + #superclass : #LWComponent, + #instVars : [ + 'classView', + 'pkgView', + 'pkgListing', + 'splitMain', + 'splitListing', + 'spotterDialog' + ], #category : #'LiveWeb-Developer' } +{ #category : #accessing } +LWDevMain >> children [ + ^ ReadStream on: { splitMain. spotterDialog } + +] + +{ #category : #initialization } +LWDevMain >> initialize [ + super initialize. + classView := LWDevClassView new. + pkgView := LWDevPackageView new classView: classView. + pkgListing := LWDevPackageMenu new pkgView: pkgView. + splitListing := SlSplitPanel new + vertical: false; + start: pkgListing; + end: pkgView. + splitMain := SlSplitPanel new + vertical: false; + start: splitListing; + end: classView. + spotterDialog := SlDialog new + className: 'spotter'; + label: 'Jump to class'; + add: (LWBlockContainer new block: [ :h | h input: { #placeholder -> 'type classname part' } ]); + yourself. + +] + +{ #category : #rendering } +LWDevMain >> render: h [ + h div: { #class -> 'lwDevPanel' } + with: [ + spotterDialog render: h. + splitMain render: h + ] +] + { #category : #accessing } LWDevMain >> view: view [ | pkgView classView | diff --git a/src/LiveWeb-Developer/LWDevPage.class.st b/src/LiveWeb-Developer/LWDevPage.class.st index 42b4fcd..dc2ae0e 100644 --- a/src/LiveWeb-Developer/LWDevPage.class.st +++ b/src/LiveWeb-Developer/LWDevPage.class.st @@ -1,6 +1,6 @@ Class { #name : #LWDevPage, - #superclass : #LWBulmaPage, + #superclass : #SlLWPage, #category : #'LiveWeb-Developer' } @@ -38,7 +38,14 @@ console.log(e.classList); exec: function(editor) { window.event.preventDefault(); lwCompileMethod(side, editor.session.getValue()); }, readOnly: true}); }'; - << (LWDevHTMLCompiler htmlToJsonScript); + << (LWDevHTMLCompiler htmlToJsonScript); + "Add shift+enter listener to open spotter" + << 'window.addEventListener("keydown", e => { + if(e.key=="Enter" && e.shiftKey) { + let spotter = document.querySelector(".spotter"); + spotter.setAttribute("open",true); + } + });'; << '' ]); yourself diff --git a/src/LiveWeb-Shoelace/SlAlert.class.st b/src/LiveWeb-Shoelace/SlAlert.class.st index ebad425..71b8b25 100644 --- a/src/LiveWeb-Shoelace/SlAlert.class.st +++ b/src/LiveWeb-Shoelace/SlAlert.class.st @@ -31,18 +31,6 @@ SlAlert >> closable: newValue [ self attrAt: 'closable' update: [ newValue ] ] -{ #category : #'as yet unclassified' } -SlAlert >> default [ - ^ self slotAt: 'default'. -] - -{ #category : #'as yet unclassified' } -SlAlert >> default: aComponentOrString [ - self slotAt: 'default' put: (aComponentOrString isString - ifTrue: [ LWBlockContainer new block: [ :h | h span: aComponentOrString ] ] - ifFalse: [ aComponentOrString ]). -] - { #category : #'as yet unclassified' } SlAlert >> duration [ ^ self attrAt: 'duration' @@ -61,9 +49,7 @@ SlAlert >> icon [ { #category : #'as yet unclassified' } SlAlert >> icon: aComponentOrString [ - self slotAt: 'icon' put: (aComponentOrString isString - ifTrue: [ LWBlockContainer new block: [ :h | h span: aComponentOrString ] ] - ifFalse: [ aComponentOrString ]). + self slotAt: 'icon' put: (self asSlotComponent: aComponentOrString). ] { #category : #'as yet unclassified' } diff --git a/src/LiveWeb-Shoelace/SlCheckbox.class.st b/src/LiveWeb-Shoelace/SlCheckbox.class.st index bc4d6e3..f750cf8 100644 --- a/src/LiveWeb-Shoelace/SlCheckbox.class.st +++ b/src/LiveWeb-Shoelace/SlCheckbox.class.st @@ -24,18 +24,6 @@ SlCheckbox >> checked: newValue [ self attrAt: 'checked' update: [ newValue ] ] -{ #category : #'as yet unclassified' } -SlCheckbox >> default [ - ^ self slotAt: 'default'. -] - -{ #category : #'as yet unclassified' } -SlCheckbox >> default: aComponentOrString [ - self slotAt: 'default' put: (aComponentOrString isString - ifTrue: [ LWBlockContainer new block: [ :h | h span: aComponentOrString ] ] - ifFalse: [ aComponentOrString ]). -] - { #category : #'as yet unclassified' } SlCheckbox >> defaultChecked [ ^ self attrAt: 'defaultChecked' diff --git a/src/LiveWeb-Shoelace/SlDialog.class.st b/src/LiveWeb-Shoelace/SlDialog.class.st new file mode 100644 index 0000000..814b7b5 --- /dev/null +++ b/src/LiveWeb-Shoelace/SlDialog.class.st @@ -0,0 +1,58 @@ +Class { + #name : #SlDialog, + #superclass : #SlElement, + #category : #'LiveWeb-Shoelace' +} + +{ #category : #'as yet unclassified' } +SlDialog class >> elementAttributes [ + ^#( + (open boolean) +) +] + +{ #category : #'as yet unclassified' } +SlDialog class >> elementSlots [ + ^#( label 'header-actions' 'footer' ) +] + +{ #category : #'as yet unclassified' } +SlDialog >> footer [ + ^ self slotAt: 'footer'. +] + +{ #category : #'as yet unclassified' } +SlDialog >> footer: aComponentOrString [ + self slotAt: 'footer' put: (self asSlotComponent: aComponentOrString). +] + +{ #category : #'as yet unclassified' } +SlDialog >> headerActions [ + ^ self slotAt: 'header-actions'. +] + +{ #category : #'as yet unclassified' } +SlDialog >> headerActions: aComponentOrString [ + self slotAt: 'header-actions' put: (self asSlotComponent: aComponentOrString). +] + +{ #category : #'as yet unclassified' } +SlDialog >> label [ + ^ self slotAt: 'label'. +] + +{ #category : #'as yet unclassified' } +SlDialog >> label: aComponentOrString [ + self slotAt: 'label' put: (self asSlotComponent: aComponentOrString). +] + +{ #category : #'as yet unclassified' } +SlDialog >> open [ + ^ self attrAt: 'open' +] + +{ #category : #'as yet unclassified' } +SlDialog >> open: newValue [ + self assert: (newValue isKindOf: Boolean). + self attrAt: 'open' update: [ newValue ] +] diff --git a/src/LiveWeb-Shoelace/SlElement.class.st b/src/LiveWeb-Shoelace/SlElement.class.st index ad13e38..90b2b00 100644 --- a/src/LiveWeb-Shoelace/SlElement.class.st +++ b/src/LiveWeb-Shoelace/SlElement.class.st @@ -16,9 +16,10 @@ SlElement class >> compileAccessors [ jsOnlyProps := self elementProperties asSet. props do: [ :p | - | pname ptype typeCheck | - pname := p first. + | pname aname ptype typeCheck | + aname := p first. ptype := p second. + pname := self kebabToCamel: aname. typeCheck := ''. ptype isArray ifTrue: [ typeCheck := 'self assert: ( #( {1} ) includes: newValue).' format: { @@ -35,10 +36,10 @@ SlElement class >> compileAccessors [ typeCheck := 'self assert: newValue isString.' ]. self compile: ('{1} - ^ self attrAt: ''{1}''' format: { pname }). + ^ self attrAt: ''{2}''' format: { pname. aname }). self compile: ('{1}: newValue {2} - self attrAt: ''{1}'' update: [ newValue ]' format: { pname. typeCheck }). + self attrAt: ''{3}'' update: [ newValue ]' format: { pname. typeCheck. aname }). ] @@ -53,13 +54,13 @@ SlElement class >> compileAll [ { #category : #compiling } SlElement class >> compileSlots [ - (self elementSlots, #(default)) do: [ :s | + self elementSlots do: [ :s | + | sel | + sel := self kebabToCamel: s. self compile: ('{1} - ^ self slotAt: ''{1}''.' format: { s }). + ^ self slotAt: ''{2}''.' format: {sel. s}). self compile: ('{1}: aComponentOrString - self slotAt: ''{1}'' put: (aComponentOrString isString - ifTrue: [ LWBlockContainer new block: [ :h | h span: aComponentOrString ] ] - ifFalse: [ aComponentOrString ]).' format: { s }) + self slotAt: ''{2}'' put: (self asSlotComponent: aComponentOrString).' format: {sel. s}) ]. ] @@ -87,15 +88,21 @@ SlElement class >> elementSlots [ ] { #category : #'as yet unclassified' } -SlElement >> default [ - ^ self slotAt: 'default'. +SlElement class >> kebabToCamel: kebab [ + | parts | + parts := kebab splitOn: $-. + ^String streamContents: [ :out | + out << parts first. + parts allButFirst do: [ :p | out << p capitalized ] + ] ] -{ #category : #'as yet unclassified' } -SlElement >> default: aComponentOrString [ - self slotAt: 'default' put: (aComponentOrString isString - ifTrue: [ LWBlockContainer new block: [ :h | h span: aComponentOrString ] ] - ifFalse: [ aComponentOrString ]). +{ #category : #converting } +SlElement >> asSlotComponent: aComponent [ + ^ (aComponent respondsTo: #slot:) + ifTrue: [ aComponent ] + ifFalse: [ LWCustomElementSlot new child: (aComponent asLWComponent) ]. + ] { #category : #'as yet unclassified' } diff --git a/src/LiveWeb-Shoelace/SlFormField.class.st b/src/LiveWeb-Shoelace/SlFormField.class.st index 7e4d7a9..d8fb1a2 100644 --- a/src/LiveWeb-Shoelace/SlFormField.class.st +++ b/src/LiveWeb-Shoelace/SlFormField.class.st @@ -26,18 +26,6 @@ SlFormField class >> elementProperties [ ] -{ #category : #'as yet unclassified' } -SlFormField >> default [ - ^ self slotAt: 'default'. -] - -{ #category : #'as yet unclassified' } -SlFormField >> default: aComponentOrString [ - self slotAt: 'default' put: (aComponentOrString isString - ifTrue: [ LWBlockContainer new block: [ :h | h span: aComponentOrString ] ] - ifFalse: [ aComponentOrString ]). -] - { #category : #'as yet unclassified' } SlFormField >> disabled [ ^ self attrAt: 'disabled' @@ -49,16 +37,6 @@ SlFormField >> disabled: newValue [ self attrAt: 'disabled' update: [ newValue ] ] -{ #category : #'as yet unclassified' } -SlFormField >> form [ - ^ containerAttributes detect: [ :a | a name = 'form' ] -] - -{ #category : #'as yet unclassified' } -SlFormField >> form: newValue [ - self attr: 'form' update: [ newValue ] -] - { #category : #'as yet unclassified' } SlFormField >> name [ ^ self attrAt: 'name' diff --git a/src/LiveWeb-Shoelace/SlInput.class.st b/src/LiveWeb-Shoelace/SlInput.class.st new file mode 100644 index 0000000..107dd01 --- /dev/null +++ b/src/LiveWeb-Shoelace/SlInput.class.st @@ -0,0 +1,340 @@ +Class { + #name : #SlInput, + #superclass : #SlFormField, + #category : #'LiveWeb-Shoelace' +} + +{ #category : #'as yet unclassified' } +SlInput class >> elementAttributes [ + ^ #( + (type (date 'datetime-local' email number password search tel text time url)) + (filled boolean) + (pill boolean) + (clearable boolean) + (placeholder string) + ('password-toggle' boolean) + ('password-visible' boolean) + ('no-spin-buttons' boolean) + (pattern string) + (minlength number) + (maxlength number) + (min number_or_string) + (max number_or_string) + (step number_or_any) + (autocapitalize (off none on sentences words characters)) + (autocorrect (off on)) + (autocomplete string) + (autofocus boolean) + (enterkeyhint (enter done go next previous search send)) + (spellcheck boolean) + (inputmode (none text decimal numeric tel search email url)) + +) +] + +{ #category : #'as yet unclassified' } +SlInput class >> elementSlots [ + ^#( label prefix suffix 'clear-icon' 'show-password-icon' 'hide-password-icon' 'help-text' ) + +] + +{ #category : #'as yet unclassified' } +SlInput >> autocapitalize [ + ^ self attrAt: 'autocapitalize' +] + +{ #category : #'as yet unclassified' } +SlInput >> autocapitalize: newValue [ + self assert: ( #( 'off' 'none' 'on' 'sentences' 'words' 'characters' ) includes: newValue). + self attrAt: 'autocapitalize' update: [ newValue ] +] + +{ #category : #'as yet unclassified' } +SlInput >> autocomplete [ + ^ self attrAt: 'autocomplete' +] + +{ #category : #'as yet unclassified' } +SlInput >> autocomplete: newValue [ + self assert: newValue isString. + self attrAt: 'autocomplete' update: [ newValue ] +] + +{ #category : #'as yet unclassified' } +SlInput >> autocorrect [ + ^ self attrAt: 'autocorrect' +] + +{ #category : #'as yet unclassified' } +SlInput >> autocorrect: newValue [ + self assert: ( #( 'off' 'on' ) includes: newValue). + self attrAt: 'autocorrect' update: [ newValue ] +] + +{ #category : #'as yet unclassified' } +SlInput >> autofocus [ + ^ self attrAt: 'autofocus' +] + +{ #category : #'as yet unclassified' } +SlInput >> autofocus: newValue [ + self assert: (newValue isKindOf: Boolean). + self attrAt: 'autofocus' update: [ newValue ] +] + +{ #category : #'as yet unclassified' } +SlInput >> clearIcon [ + ^ self slotAt: 'clear-icon'. +] + +{ #category : #'as yet unclassified' } +SlInput >> clearIcon: aComponentOrString [ + self slotAt: 'clear-icon' put: (self asSlotComponent: aComponentOrString). +] + +{ #category : #'as yet unclassified' } +SlInput >> clearable [ + ^ self attrAt: 'clearable' +] + +{ #category : #'as yet unclassified' } +SlInput >> clearable: newValue [ + self assert: (newValue isKindOf: Boolean). + self attrAt: 'clearable' update: [ newValue ] +] + +{ #category : #'as yet unclassified' } +SlInput >> enterkeyhint [ + ^ self attrAt: 'enterkeyhint' +] + +{ #category : #'as yet unclassified' } +SlInput >> enterkeyhint: newValue [ + self assert: ( #( 'enter' 'done' 'go' 'next' 'previous' 'search' 'send' ) includes: newValue). + self attrAt: 'enterkeyhint' update: [ newValue ] +] + +{ #category : #'as yet unclassified' } +SlInput >> filled [ + ^ self attrAt: 'filled' +] + +{ #category : #'as yet unclassified' } +SlInput >> filled: newValue [ + self assert: (newValue isKindOf: Boolean). + self attrAt: 'filled' update: [ newValue ] +] + +{ #category : #'as yet unclassified' } +SlInput >> helpText [ + ^ self slotAt: 'help-text'. +] + +{ #category : #'as yet unclassified' } +SlInput >> helpText: aComponentOrString [ + self slotAt: 'help-text' put: (self asSlotComponent: aComponentOrString). +] + +{ #category : #'as yet unclassified' } +SlInput >> hidePasswordIcon [ + ^ self slotAt: 'hide-password-icon'. +] + +{ #category : #'as yet unclassified' } +SlInput >> hidePasswordIcon: aComponentOrString [ + self slotAt: 'hide-password-icon' put: (self asSlotComponent: aComponentOrString). +] + +{ #category : #'as yet unclassified' } +SlInput >> inputmode [ + ^ self attrAt: 'inputmode' +] + +{ #category : #'as yet unclassified' } +SlInput >> inputmode: newValue [ + self assert: ( #( 'none' 'text' 'decimal' 'numeric' 'tel' 'search' 'email' 'url' ) includes: newValue). + self attrAt: 'inputmode' update: [ newValue ] +] + +{ #category : #'as yet unclassified' } +SlInput >> label [ + ^ self slotAt: 'label'. +] + +{ #category : #'as yet unclassified' } +SlInput >> label: aComponentOrString [ + self slotAt: 'label' put: (self asSlotComponent: aComponentOrString). +] + +{ #category : #'as yet unclassified' } +SlInput >> max [ + ^ self attrAt: 'max' +] + +{ #category : #'as yet unclassified' } +SlInput >> max: newValue [ + + self attrAt: 'max' update: [ newValue ] +] + +{ #category : #'as yet unclassified' } +SlInput >> maxlength [ + ^ self attrAt: 'maxlength' +] + +{ #category : #'as yet unclassified' } +SlInput >> maxlength: newValue [ + self assert: newValue isNumber. + self attrAt: 'maxlength' update: [ newValue ] +] + +{ #category : #'as yet unclassified' } +SlInput >> min [ + ^ self attrAt: 'min' +] + +{ #category : #'as yet unclassified' } +SlInput >> min: newValue [ + + self attrAt: 'min' update: [ newValue ] +] + +{ #category : #'as yet unclassified' } +SlInput >> minlength [ + ^ self attrAt: 'minlength' +] + +{ #category : #'as yet unclassified' } +SlInput >> minlength: newValue [ + self assert: newValue isNumber. + self attrAt: 'minlength' update: [ newValue ] +] + +{ #category : #'as yet unclassified' } +SlInput >> noSpinButtons [ + ^ self attrAt: 'no-spin-buttons' +] + +{ #category : #'as yet unclassified' } +SlInput >> noSpinButtons: newValue [ + self assert: (newValue isKindOf: Boolean). + self attrAt: 'no-spin-buttons' update: [ newValue ] +] + +{ #category : #'as yet unclassified' } +SlInput >> passwordToggle [ + ^ self attrAt: 'password-toggle' +] + +{ #category : #'as yet unclassified' } +SlInput >> passwordToggle: newValue [ + self assert: (newValue isKindOf: Boolean). + self attrAt: 'password-toggle' update: [ newValue ] +] + +{ #category : #'as yet unclassified' } +SlInput >> passwordVisible [ + ^ self attrAt: 'password-visible' +] + +{ #category : #'as yet unclassified' } +SlInput >> passwordVisible: newValue [ + self assert: (newValue isKindOf: Boolean). + self attrAt: 'password-visible' update: [ newValue ] +] + +{ #category : #'as yet unclassified' } +SlInput >> pattern [ + ^ self attrAt: 'pattern' +] + +{ #category : #'as yet unclassified' } +SlInput >> pattern: newValue [ + self assert: newValue isString. + self attrAt: 'pattern' update: [ newValue ] +] + +{ #category : #'as yet unclassified' } +SlInput >> pill [ + ^ self attrAt: 'pill' +] + +{ #category : #'as yet unclassified' } +SlInput >> pill: newValue [ + self assert: (newValue isKindOf: Boolean). + self attrAt: 'pill' update: [ newValue ] +] + +{ #category : #'as yet unclassified' } +SlInput >> placeholder [ + ^ self attrAt: 'placeholder' +] + +{ #category : #'as yet unclassified' } +SlInput >> placeholder: newValue [ + self assert: newValue isString. + self attrAt: 'placeholder' update: [ newValue ] +] + +{ #category : #'as yet unclassified' } +SlInput >> prefix [ + ^ self slotAt: 'prefix'. +] + +{ #category : #'as yet unclassified' } +SlInput >> prefix: aComponentOrString [ + self slotAt: 'prefix' put: (self asSlotComponent: aComponentOrString). +] + +{ #category : #'as yet unclassified' } +SlInput >> showPasswordIcon [ + ^ self slotAt: 'show-password-icon'. +] + +{ #category : #'as yet unclassified' } +SlInput >> showPasswordIcon: aComponentOrString [ + self slotAt: 'show-password-icon' put: (self asSlotComponent: aComponentOrString). +] + +{ #category : #'as yet unclassified' } +SlInput >> spellcheck [ + ^ self attrAt: 'spellcheck' +] + +{ #category : #'as yet unclassified' } +SlInput >> spellcheck: newValue [ + self assert: (newValue isKindOf: Boolean). + self attrAt: 'spellcheck' update: [ newValue ] +] + +{ #category : #'as yet unclassified' } +SlInput >> step [ + ^ self attrAt: 'step' +] + +{ #category : #'as yet unclassified' } +SlInput >> step: newValue [ + + self attrAt: 'step' update: [ newValue ] +] + +{ #category : #'as yet unclassified' } +SlInput >> suffix [ + ^ self slotAt: 'suffix'. +] + +{ #category : #'as yet unclassified' } +SlInput >> suffix: aComponentOrString [ + self slotAt: 'suffix' put: (self asSlotComponent: aComponentOrString). +] + +{ #category : #'as yet unclassified' } +SlInput >> type [ + ^ self attrAt: 'type' +] + +{ #category : #'as yet unclassified' } +SlInput >> type: newValue [ + self assert: ( #( 'date' 'datetime-local' 'email' 'number' 'password' 'search' 'tel' 'text' 'time' 'url' ) includes: newValue). + self attrAt: 'type' update: [ newValue ] +] diff --git a/src/LiveWeb-Shoelace/SlSplitPanel.class.st b/src/LiveWeb-Shoelace/SlSplitPanel.class.st new file mode 100644 index 0000000..f8a2f10 --- /dev/null +++ b/src/LiveWeb-Shoelace/SlSplitPanel.class.st @@ -0,0 +1,137 @@ +Class { + #name : #SlSplitPanel, + #superclass : #SlElement, + #instVars : [ + 'slot' + ], + #category : #'LiveWeb-Shoelace' +} + +{ #category : #'as yet unclassified' } +SlSplitPanel class >> elementAttributes [ + ^#( + ( position number ) + ( vertical boolean ) + ( disabled boolean ) + ( primary (start end) ) + ( snap string ) + ( snapThreshold number ) +) +] + +{ #category : #'as yet unclassified' } +SlSplitPanel class >> elementSlots [ + ^ #( start end divider ) + +] + +{ #category : #'as yet unclassified' } +SlSplitPanel >> disabled [ + ^ self attrAt: 'disabled' +] + +{ #category : #'as yet unclassified' } +SlSplitPanel >> disabled: newValue [ + self assert: (newValue isKindOf: Boolean). + self attrAt: 'disabled' update: [ newValue ] +] + +{ #category : #'as yet unclassified' } +SlSplitPanel >> divider [ + ^ self slotAt: 'divider'. +] + +{ #category : #'as yet unclassified' } +SlSplitPanel >> divider: aComponentOrString [ + self slotAt: 'divider' put: (self asSlotComponent: aComponentOrString). +] + +{ #category : #'as yet unclassified' } +SlSplitPanel >> end [ + ^ self slotAt: 'end'. +] + +{ #category : #'as yet unclassified' } +SlSplitPanel >> end: aComponentOrString [ + self slotAt: 'end' put: (self asSlotComponent: aComponentOrString). +] + +{ #category : #'as yet unclassified' } +SlSplitPanel >> position [ + ^ self attrAt: 'position' +] + +{ #category : #'as yet unclassified' } +SlSplitPanel >> position: newValue [ + self assert: newValue isNumber. + self attrAt: 'position' update: [ newValue ] +] + +{ #category : #'as yet unclassified' } +SlSplitPanel >> primary [ + ^ self attrAt: 'primary' +] + +{ #category : #'as yet unclassified' } +SlSplitPanel >> primary: newValue [ + self assert: ( #( 'start' 'end' ) includes: newValue). + self attrAt: 'primary' update: [ newValue ] +] + +{ #category : #rendering } +SlSplitPanel >> renderOn: h [ + slot + ifNil: [ super renderOn: h ] + ifNotNil: [ h div: { #style->'display: inline-block;'. #slot -> slot } with: [ super renderOn: h ] ] + +] + +{ #category : #'as yet unclassified' } +SlSplitPanel >> slot: slotName [ + "Set the slot name if this panel is a slot in a parent panel. + An inline-block div will be rendered around the element." + slot := slotName. +] + +{ #category : #'as yet unclassified' } +SlSplitPanel >> snap [ + ^ self attrAt: 'snap' +] + +{ #category : #'as yet unclassified' } +SlSplitPanel >> snap: newValue [ + self assert: newValue isString. + self attrAt: 'snap' update: [ newValue ] +] + +{ #category : #'as yet unclassified' } +SlSplitPanel >> snapThreshold [ + ^ self attrAt: 'snapThreshold' +] + +{ #category : #'as yet unclassified' } +SlSplitPanel >> snapThreshold: newValue [ + self assert: newValue isNumber. + self attrAt: 'snapThreshold' update: [ newValue ] +] + +{ #category : #'as yet unclassified' } +SlSplitPanel >> start [ + ^ self slotAt: 'start'. +] + +{ #category : #'as yet unclassified' } +SlSplitPanel >> start: aComponentOrString [ + self slotAt: 'start' put: (self asSlotComponent: aComponentOrString). +] + +{ #category : #'as yet unclassified' } +SlSplitPanel >> vertical [ + ^ self attrAt: 'vertical' +] + +{ #category : #'as yet unclassified' } +SlSplitPanel >> vertical: newValue [ + self assert: (newValue isKindOf: Boolean). + self attrAt: 'vertical' update: [ newValue ] +]