From 71695e4eea5b8183a21624d524f84dd3127f1f16 Mon Sep 17 00:00:00 2001 From: hoemac Date: Tue, 26 Oct 2021 10:48:34 +0200 Subject: [PATCH 1/2] MDLTabWidget saves the current tab for refresh: show the previously selected tab --- .../BlockClosure.extension.st | 12 +- .../MDLAbstractFilter.class.st | 62 +- .../MDLAbstractFooterLinksList.class.st | 96 +- .../MDLAbstractHeaderSection.class.st | 28 +- .../MDLAbstractLayoutSection.class.st | 46 +- .../MDLAjaxButtonColumnDescription.class.st | 62 +- .../MDLAjaxExpansionStrategy.class.st | 76 +- .../MDLBeginsWithFilter.class.st | 26 +- .../MDLButtonColumnDescription.class.st | 174 +-- .../MDLCalendar.class.st | 262 ++-- .../MDLCardActionsWidget.class.st | 88 +- .../MDLCardMediaWidget.class.st | 56 +- .../MDLCardTextContainerWidget.class.st | 78 +- .../MDLCardTitle.class.st | 126 +- .../MDLCardWidget.class.st | 292 ++-- .../MDLContentCenterer.class.st | 140 +- .../MDLDatePicker.class.st | 52 +- .../MDLDialogWidget.class.st | 352 ++--- .../MDLExpansionPanel.class.st | 324 ++-- .../MDLExpansionStrategy.class.st | 46 +- .../MDLFlatDatePicker.class.st | 672 ++++----- .../MDLFooter.class.st | 164 +-- .../MDLFooterAbstractSection.class.st | 30 +- .../MDLFooterComponentsSection.class.st | 36 +- .../MDLFooterDropdownSection.class.st | 48 +- .../MDLFooterLinksSection.class.st | 48 +- .../MDLFooterNilSection.class.st | 40 +- .../MDLHideExpansionStrategy.class.st | 44 +- .../MDLHighLevelWidget.class.st | 228 +-- .../MDLIconComponent.class.st | 58 +- .../MDLIconDrawerSection.class.st | 52 +- .../MDLInsensitiveBeginsWithFilter.class.st | 26 +- .../MDLInsensitiveSubstringFilter.class.st | 26 +- .../MDLLayoutWidget.class.st | 220 +-- .../MDLLazyExpansionStrategy.class.st | 84 +- .../MDLLinkingLayoutSection.class.st | 78 +- .../MDLListIconComponent.class.st | 114 +- .../MDLLoginCardWidget.class.st | 42 +- .../MDLLoginDialogWidget.class.st | 152 +- .../MDLLoginWidget.class.st | 294 ++-- .../MDLMegaFooterLinksList.class.st | 22 +- .../MDLMenuButtonWidget.class.st | 552 +++---- .../MDLMiniFooterLinksList.class.st | 22 +- ...DLNavigationLinkWithIconComponent.class.st | 108 +- .../MDLNestedList.class.st | 1302 ++++++++--------- ...tedListItemRenderAbstractStrategy.class.st | 442 +++--- ...LNestedListItemRenderAjaxStrategy.class.st | 44 +- ...estedListItemRenderAnchorStrategy.class.st | 112 +- .../MDLNestedListTreeNode.class.st | 134 +- .../MDLNewPasswordWidget.class.st | 300 ++-- .../MDLNilLayoutSection.class.st | 20 +- .../MDLNumericColumnDescription.class.st | 50 +- .../MDLPoll.class.st | 122 +- .../MDLPollWidget.class.st | 196 +-- .../MDLProgressBarWidget.class.st | 256 ++-- .../MDLPseudoRegexFilter.class.st | 62 +- .../MDLSelectWidget.class.st | 866 +++++------ .../MDLSimpleDrawerSection.class.st | 24 +- .../MDLSimpleRowHeaderSection.class.st | 30 +- .../MDLSmallFooter.class.st | 88 +- .../MDLSortableTable.class.st | 652 ++++----- .../MDLSortableTableHeader.class.st | 180 +-- ...TableHeaderElementSortedAscending.class.st | 44 +- ...ableHeaderElementSortedDescending.class.st | 44 +- ...ortableTableHeaderElementUnsorted.class.st | 42 +- .../MDLSortableTableHeaderNumeric.class.st | 34 +- .../MDLSortableTableHeaderState.class.st | 86 +- .../MDLStringColumnDescription.class.st | 54 +- .../MDLSubstringFilter.class.st | 26 +- .../MDLSwitchWidget.class.st | 34 +- .../MDLTabWidget.class.st | 106 +- .../MDLTableColumnDescription.class.st | 152 +- .../MDLTableWidget.class.st | 248 ++-- .../MDLTextAreaWidget.class.st | 50 +- .../MDLTextFieldWidget.class.st | 378 ++--- .../MDLWidget.class.st | 110 +- ...ManifestMaterialDesignLiteWidgets.class.st | 70 +- .../Object.extension.st | 22 +- .../SequenceableCollection.extension.st | 26 +- .../Symbol.extension.st | 22 +- src/Material-Design-Lite-Widgets/package.st | 2 +- 81 files changed, 6003 insertions(+), 5985 deletions(-) diff --git a/src/Material-Design-Lite-Widgets/BlockClosure.extension.st b/src/Material-Design-Lite-Widgets/BlockClosure.extension.st index 7a37732c..8ef08634 100644 --- a/src/Material-Design-Lite-Widgets/BlockClosure.extension.st +++ b/src/Material-Design-Lite-Widgets/BlockClosure.extension.st @@ -1,6 +1,6 @@ -Extension { #name : #BlockClosure } - -{ #category : #'*Material-Design-Lite-Widgets' } -BlockClosure >> mdlCull: firstArg cull: secondArg [ - ^ self cull: firstArg cull: secondArg -] +Extension { #name : #BlockClosure } + +{ #category : #'*Material-Design-Lite-Widgets' } +BlockClosure >> mdlCull: firstArg cull: secondArg [ + ^ self cull: firstArg cull: secondArg +] diff --git a/src/Material-Design-Lite-Widgets/MDLAbstractFilter.class.st b/src/Material-Design-Lite-Widgets/MDLAbstractFilter.class.st index 8cc0bb48..e6168d2a 100644 --- a/src/Material-Design-Lite-Widgets/MDLAbstractFilter.class.st +++ b/src/Material-Design-Lite-Widgets/MDLAbstractFilter.class.st @@ -1,31 +1,31 @@ -" -I am an abstract class managing the filtering of a nested list. I act in a design pattern strategy. - -My subclasses should be able to filter a MDLNestedList. - -Public API and Key Messages - -- class>>#isMatching: aString with: aPattern Return a boolean. True if the pattern matches the string, else false. -" -Class { - #name : #MDLAbstractFilter, - #superclass : #Object, - #category : #'Material-Design-Lite-Widgets-List' -} - -{ #category : #accessing } -MDLAbstractFilter class >> formatedElement: aString matches: aPattern [ - ^ self subclassResponsibility -] - -{ #category : #testing } -MDLAbstractFilter class >> isAbstract [ - ^ self = MDLAbstractFilter -] - -{ #category : #accessing } -MDLAbstractFilter class >> selectMatchingFrom: aCollection format: aFormatBlock with: aPattern [ - "I take as parameter a collection of elements to match, a block to get the readable format of the element and a pattern and I should return a collection of elements matching the pattern in their readable format." - - ^ aCollection select: [ :each | self formatedElement: (aFormatBlock value: each) matches: aPattern ] -] +" +I am an abstract class managing the filtering of a nested list. I act in a design pattern strategy. + +My subclasses should be able to filter a MDLNestedList. + +Public API and Key Messages + +- class>>#isMatching: aString with: aPattern Return a boolean. True if the pattern matches the string, else false. +" +Class { + #name : #MDLAbstractFilter, + #superclass : #Object, + #category : #'Material-Design-Lite-Widgets-List' +} + +{ #category : #accessing } +MDLAbstractFilter class >> formatedElement: aString matches: aPattern [ + ^ self subclassResponsibility +] + +{ #category : #testing } +MDLAbstractFilter class >> isAbstract [ + ^ self = MDLAbstractFilter +] + +{ #category : #accessing } +MDLAbstractFilter class >> selectMatchingFrom: aCollection format: aFormatBlock with: aPattern [ + "I take as parameter a collection of elements to match, a block to get the readable format of the element and a pattern and I should return a collection of elements matching the pattern in their readable format." + + ^ aCollection select: [ :each | self formatedElement: (aFormatBlock value: each) matches: aPattern ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLAbstractFooterLinksList.class.st b/src/Material-Design-Lite-Widgets/MDLAbstractFooterLinksList.class.st index 1f1516a5..939574e2 100644 --- a/src/Material-Design-Lite-Widgets/MDLAbstractFooterLinksList.class.st +++ b/src/Material-Design-Lite-Widgets/MDLAbstractFooterLinksList.class.st @@ -1,48 +1,48 @@ -Class { - #name : #MDLAbstractFooterLinksList, - #superclass : #Object, - #instVars : [ - 'links', - 'title' - ], - #category : 'Material-Design-Lite-Widgets-Footer' -} - -{ #category : #adding } -MDLAbstractFooterLinksList >> addLinks: l [ - "Links must be formatted as followed" - title := l key. - links addAll: l value -] - -{ #category : #initialization } -MDLAbstractFooterLinksList >> initialize [ - super initialize. - links := OrderedDictionary new -] - -{ #category : #'as yet unclassified' } -MDLAbstractFooterLinksList >> renderLinksListOn: html [ - self subclassResponsibility -] - -{ #category : #'as yet unclassified' } -MDLAbstractFooterLinksList >> renderLinksOn: html [ - links keysAndValuesDo: [ :label :callback | - html listItem: [ - html anchor - callback: callback; - with: label ] ] -] - -{ #category : #'as yet unclassified' } -MDLAbstractFooterLinksList >> renderLinksWithHeaderOn: html [ - html mdlFooterHeading: title. - self renderLinksListOn: html -] - -{ #category : #'as yet unclassified' } -MDLAbstractFooterLinksList >> renderLinksWithLogoOn: html [ - html mdlLogo: title. - self renderLinksListOn: html -] +Class { + #name : #MDLAbstractFooterLinksList, + #superclass : #Object, + #instVars : [ + 'links', + 'title' + ], + #category : 'Material-Design-Lite-Widgets-Footer' +} + +{ #category : #adding } +MDLAbstractFooterLinksList >> addLinks: l [ + "Links must be formatted as followed" + title := l key. + links addAll: l value +] + +{ #category : #initialization } +MDLAbstractFooterLinksList >> initialize [ + super initialize. + links := OrderedDictionary new +] + +{ #category : #'as yet unclassified' } +MDLAbstractFooterLinksList >> renderLinksListOn: html [ + self subclassResponsibility +] + +{ #category : #'as yet unclassified' } +MDLAbstractFooterLinksList >> renderLinksOn: html [ + links keysAndValuesDo: [ :label :callback | + html listItem: [ + html anchor + callback: callback; + with: label ] ] +] + +{ #category : #'as yet unclassified' } +MDLAbstractFooterLinksList >> renderLinksWithHeaderOn: html [ + html mdlFooterHeading: title. + self renderLinksListOn: html +] + +{ #category : #'as yet unclassified' } +MDLAbstractFooterLinksList >> renderLinksWithLogoOn: html [ + html mdlLogo: title. + self renderLinksListOn: html +] diff --git a/src/Material-Design-Lite-Widgets/MDLAbstractHeaderSection.class.st b/src/Material-Design-Lite-Widgets/MDLAbstractHeaderSection.class.st index c1c685c4..370e5019 100644 --- a/src/Material-Design-Lite-Widgets/MDLAbstractHeaderSection.class.st +++ b/src/Material-Design-Lite-Widgets/MDLAbstractHeaderSection.class.st @@ -1,14 +1,14 @@ -Class { - #name : #MDLAbstractHeaderSection, - #superclass : #MDLLinkingLayoutSection, - #instVars : [ - 'brush' - ], - #category : 'Material-Design-Lite-Widgets-Header' -} - -{ #category : #initialization } -MDLAbstractHeaderSection >> initialize [ - super initialize. - brush := MDLLayoutHeader new -] +Class { + #name : #MDLAbstractHeaderSection, + #superclass : #MDLLinkingLayoutSection, + #instVars : [ + 'brush' + ], + #category : 'Material-Design-Lite-Widgets-Header' +} + +{ #category : #initialization } +MDLAbstractHeaderSection >> initialize [ + super initialize. + brush := MDLLayoutHeader new +] diff --git a/src/Material-Design-Lite-Widgets/MDLAbstractLayoutSection.class.st b/src/Material-Design-Lite-Widgets/MDLAbstractLayoutSection.class.st index 2ca80d24..ca60fe49 100644 --- a/src/Material-Design-Lite-Widgets/MDLAbstractLayoutSection.class.st +++ b/src/Material-Design-Lite-Widgets/MDLAbstractLayoutSection.class.st @@ -1,23 +1,23 @@ -Class { - #name : #MDLAbstractLayoutSection, - #superclass : #MDLWidget, - #instVars : [ - 'layout' - ], - #category : 'Material-Design-Lite-Widgets-Header' -} - -{ #category : #accessing } -MDLAbstractLayoutSection >> layout [ - ^ layout -] - -{ #category : #accessing } -MDLAbstractLayoutSection >> layout: anObject [ - layout := anObject -] - -{ #category : #rendering } -MDLAbstractLayoutSection >> renderContentOn: html [ - self subclassResponsibility -] +Class { + #name : #MDLAbstractLayoutSection, + #superclass : #MDLWidget, + #instVars : [ + 'layout' + ], + #category : 'Material-Design-Lite-Widgets-Header' +} + +{ #category : #accessing } +MDLAbstractLayoutSection >> layout [ + ^ layout +] + +{ #category : #accessing } +MDLAbstractLayoutSection >> layout: anObject [ + layout := anObject +] + +{ #category : #rendering } +MDLAbstractLayoutSection >> renderContentOn: html [ + self subclassResponsibility +] diff --git a/src/Material-Design-Lite-Widgets/MDLAjaxButtonColumnDescription.class.st b/src/Material-Design-Lite-Widgets/MDLAjaxButtonColumnDescription.class.st index 6e2a97ef..41e553db 100644 --- a/src/Material-Design-Lite-Widgets/MDLAjaxButtonColumnDescription.class.st +++ b/src/Material-Design-Lite-Widgets/MDLAjaxButtonColumnDescription.class.st @@ -1,31 +1,31 @@ -" -I am a button performing its action via AJAX which means that my user control what parts of the page need to be refreshed. - -My #onClickBlock has two arguments: the html canvas to generate javascript on and the row on which the action should be applied. -" -Class { - #name : #MDLAjaxButtonColumnDescription, - #superclass : #MDLButtonColumnDescription, - #category : #'Material-Design-Lite-Widgets-Table' -} - -{ #category : #initialization } -MDLAjaxButtonColumnDescription >> initialize [ - super initialize. - "Initialize with a behaviour that does nothing." - self onClickBlock: [ :html :rowObject | html jQuery noop ] -] - -{ #category : #rendering } -MDLAjaxButtonColumnDescription >> render: row on: html [ - | buttonId | - html mdlTableCell - with: [ - html mdlButton - class: 'mdl-table-widget__cell--button'; - id: (buttonId := self generateIdUsing: html); - onClick: (self onClickBlock value: html value: row); - labelIcon: self iconName ]. - - self renderTooltipFor: buttonId on: html -] +" +I am a button performing its action via AJAX which means that my user control what parts of the page need to be refreshed. + +My #onClickBlock has two arguments: the html canvas to generate javascript on and the row on which the action should be applied. +" +Class { + #name : #MDLAjaxButtonColumnDescription, + #superclass : #MDLButtonColumnDescription, + #category : #'Material-Design-Lite-Widgets-Table' +} + +{ #category : #initialization } +MDLAjaxButtonColumnDescription >> initialize [ + super initialize. + "Initialize with a behaviour that does nothing." + self onClickBlock: [ :html :rowObject | html jQuery noop ] +] + +{ #category : #rendering } +MDLAjaxButtonColumnDescription >> render: row on: html [ + | buttonId | + html mdlTableCell + with: [ + html mdlButton + class: 'mdl-table-widget__cell--button'; + id: (buttonId := self generateIdUsing: html); + onClick: (self onClickBlock value: html value: row); + labelIcon: self iconName ]. + + self renderTooltipFor: buttonId on: html +] diff --git a/src/Material-Design-Lite-Widgets/MDLAjaxExpansionStrategy.class.st b/src/Material-Design-Lite-Widgets/MDLAjaxExpansionStrategy.class.st index b8a98e78..74897387 100644 --- a/src/Material-Design-Lite-Widgets/MDLAjaxExpansionStrategy.class.st +++ b/src/Material-Design-Lite-Widgets/MDLAjaxExpansionStrategy.class.st @@ -1,38 +1,38 @@ -" -I am display strategy that uses AJAX to reload the entire MDLExpansionPanel each time the toggle button is clicked. - -Because of my behaviour, one can define an action to execute on server side either when I expand (#onExpandBlock:) or when I fold (#onFoldBlock:). -These actions can eventually modify the state of the expansion panel as the full widget is reload via AJAX. -" -Class { - #name : #MDLAjaxExpansionStrategy, - #superclass : #MDLExpansionStrategy, - #instVars : [ - 'onFoldBlock', - 'onExpandBlock' - ], - #category : #'Material-Design-Lite-Widgets-Expansion' -} - -{ #category : #javascript } -MDLAjaxExpansionStrategy >> customize: anExpansionPanelHeader in: anExpansionPanel on: html [ - anExpansionPanelHeader - onClick: - ((html jQuery this parent find: '.mdl-expansion-panel__content') load - html: [ :ajaxHtmlCanvas | - anExpansionPanel - toggleExpansion; - renderExpansionPanelContentOn: ajaxHtmlCanvas ]; - onComplete: 'componentHandler.upgradeElements(this);' js) -] - -{ #category : #testing } -MDLAjaxExpansionStrategy >> isAjaxExpansionStrategy [ - ^ true -] - -{ #category : #rendering } -MDLAjaxExpansionStrategy >> renderExpansionPanel: anExpansionPanel contentOn: html [ - anExpansionPanel isExpanded - ifTrue: [ anExpansionPanel expandedBlock value: html ] -] +" +I am display strategy that uses AJAX to reload the entire MDLExpansionPanel each time the toggle button is clicked. + +Because of my behaviour, one can define an action to execute on server side either when I expand (#onExpandBlock:) or when I fold (#onFoldBlock:). +These actions can eventually modify the state of the expansion panel as the full widget is reload via AJAX. +" +Class { + #name : #MDLAjaxExpansionStrategy, + #superclass : #MDLExpansionStrategy, + #instVars : [ + 'onFoldBlock', + 'onExpandBlock' + ], + #category : #'Material-Design-Lite-Widgets-Expansion' +} + +{ #category : #javascript } +MDLAjaxExpansionStrategy >> customize: anExpansionPanelHeader in: anExpansionPanel on: html [ + anExpansionPanelHeader + onClick: + ((html jQuery this parent find: '.mdl-expansion-panel__content') load + html: [ :ajaxHtmlCanvas | + anExpansionPanel + toggleExpansion; + renderExpansionPanelContentOn: ajaxHtmlCanvas ]; + onComplete: 'componentHandler.upgradeElements(this);' js) +] + +{ #category : #testing } +MDLAjaxExpansionStrategy >> isAjaxExpansionStrategy [ + ^ true +] + +{ #category : #rendering } +MDLAjaxExpansionStrategy >> renderExpansionPanel: anExpansionPanel contentOn: html [ + anExpansionPanel isExpanded + ifTrue: [ anExpansionPanel expandedBlock value: html ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLBeginsWithFilter.class.st b/src/Material-Design-Lite-Widgets/MDLBeginsWithFilter.class.st index e53ee53e..69414fb4 100644 --- a/src/Material-Design-Lite-Widgets/MDLBeginsWithFilter.class.st +++ b/src/Material-Design-Lite-Widgets/MDLBeginsWithFilter.class.st @@ -1,13 +1,13 @@ -" -I am a nested list filter keeping only elements whose name begins with the pattern passed by the user. -" -Class { - #name : #MDLBeginsWithFilter, - #superclass : #MDLAbstractFilter, - #category : 'Material-Design-Lite-Widgets-List' -} - -{ #category : #accessing } -MDLBeginsWithFilter class >> formatedElement: aString matches: aPattern [ - ^ aString beginsWith: aPattern -] +" +I am a nested list filter keeping only elements whose name begins with the pattern passed by the user. +" +Class { + #name : #MDLBeginsWithFilter, + #superclass : #MDLAbstractFilter, + #category : 'Material-Design-Lite-Widgets-List' +} + +{ #category : #accessing } +MDLBeginsWithFilter class >> formatedElement: aString matches: aPattern [ + ^ aString beginsWith: aPattern +] diff --git a/src/Material-Design-Lite-Widgets/MDLButtonColumnDescription.class.st b/src/Material-Design-Lite-Widgets/MDLButtonColumnDescription.class.st index 6fb9f732..28b5e00a 100644 --- a/src/Material-Design-Lite-Widgets/MDLButtonColumnDescription.class.st +++ b/src/Material-Design-Lite-Widgets/MDLButtonColumnDescription.class.st @@ -1,87 +1,87 @@ -" -I model a button column. - -I add a button to each row which should perform an action concerning the row. - -I perform my action in a callback which means that the page is refreshed when a button is clicked. - -My #onClickBlock has a single argument: the row on which the action should be applied. - -A #tooltip can bet set to display useful information to user about the purpose of my buttons. -" -Class { - #name : #MDLButtonColumnDescription, - #superclass : #MDLTableColumnDescription, - #instVars : [ - 'onClickBlock', - 'iconName', - 'tooltip' - ], - #category : #'Material-Design-Lite-Widgets-Table' -} - -{ #category : #accessing } -MDLButtonColumnDescription >> iconName [ - ^ iconName -] - -{ #category : #accessing } -MDLButtonColumnDescription >> iconName: anObject [ - iconName := anObject -] - -{ #category : #initialization } -MDLButtonColumnDescription >> initialize [ - super initialize. - "Initialize with a behaviour that does nothing." - self onClickBlock: [ ] -] - -{ #category : #accessing } -MDLButtonColumnDescription >> onClickBlock [ - ^ onClickBlock -] - -{ #category : #accessing } -MDLButtonColumnDescription >> onClickBlock: anObject [ - onClickBlock := anObject -] - -{ #category : #rendering } -MDLButtonColumnDescription >> render: row on: html [ - | buttonId | - html mdlTableCell - class: 'mdl-table-widget__cell--button'; - with: [ html mdlAnchorButton - id: (buttonId := self generateIdUsing: html); - callback: [ self onClickBlock value: row ]; - icon: self iconName ]. - - self renderTooltipFor: buttonId on: html -] - -{ #category : #rendering } -MDLButtonColumnDescription >> renderHeadingOn: html [ - (super renderHeadingOn: html) - class: 'mdl-table-widget__cell--button'; - nonNumerical; - with: self title. -] - -{ #category : #rendering } -MDLButtonColumnDescription >> renderTooltipFor: buttonId on: html [ - self tooltip ifNil: [ ^ self ]. - html mdlTooltip - for: buttonId; - with: [ html text: self tooltip ] -] - -{ #category : #accessing } -MDLButtonColumnDescription >> tooltip [ - ^ tooltip -] - -{ #category : #accessing } -MDLButtonColumnDescription >> tooltip: anObject [ - tooltip := anObject -] +" +I model a button column. + +I add a button to each row which should perform an action concerning the row. + +I perform my action in a callback which means that the page is refreshed when a button is clicked. + +My #onClickBlock has a single argument: the row on which the action should be applied. + +A #tooltip can bet set to display useful information to user about the purpose of my buttons. +" +Class { + #name : #MDLButtonColumnDescription, + #superclass : #MDLTableColumnDescription, + #instVars : [ + 'onClickBlock', + 'iconName', + 'tooltip' + ], + #category : #'Material-Design-Lite-Widgets-Table' +} + +{ #category : #accessing } +MDLButtonColumnDescription >> iconName [ + ^ iconName +] + +{ #category : #accessing } +MDLButtonColumnDescription >> iconName: anObject [ + iconName := anObject +] + +{ #category : #initialization } +MDLButtonColumnDescription >> initialize [ + super initialize. + "Initialize with a behaviour that does nothing." + self onClickBlock: [ ] +] + +{ #category : #accessing } +MDLButtonColumnDescription >> onClickBlock [ + ^ onClickBlock +] + +{ #category : #accessing } +MDLButtonColumnDescription >> onClickBlock: anObject [ + onClickBlock := anObject +] + +{ #category : #rendering } +MDLButtonColumnDescription >> render: row on: html [ + | buttonId | + html mdlTableCell + class: 'mdl-table-widget__cell--button'; + with: [ html mdlAnchorButton + id: (buttonId := self generateIdUsing: html); + callback: [ self onClickBlock value: row ]; + icon: self iconName ]. + + self renderTooltipFor: buttonId on: html +] + +{ #category : #rendering } +MDLButtonColumnDescription >> renderHeadingOn: html [ + (super renderHeadingOn: html) + class: 'mdl-table-widget__cell--button'; + nonNumerical; + with: self title. +] + +{ #category : #rendering } +MDLButtonColumnDescription >> renderTooltipFor: buttonId on: html [ + self tooltip ifNil: [ ^ self ]. + html mdlTooltip + for: buttonId; + with: [ html text: self tooltip ] +] + +{ #category : #accessing } +MDLButtonColumnDescription >> tooltip [ + ^ tooltip +] + +{ #category : #accessing } +MDLButtonColumnDescription >> tooltip: anObject [ + tooltip := anObject +] diff --git a/src/Material-Design-Lite-Widgets/MDLCalendar.class.st b/src/Material-Design-Lite-Widgets/MDLCalendar.class.st index 657d94e6..e2619763 100644 --- a/src/Material-Design-Lite-Widgets/MDLCalendar.class.st +++ b/src/Material-Design-Lite-Widgets/MDLCalendar.class.st @@ -1,131 +1,131 @@ -" -firstDayOfWeekIndex is the index of the first day of the week in the representation, 7 being saturday and 1 sunday -" -Class { - #name : #MDLCalendar, - #superclass : #Object, - #instVars : [ - 'currentDate', - 'firstDayOfWeekIndex', - 'yearsInterval' - ], - #category : 'Material-Design-Lite-Widgets-Calendar' -} - -{ #category : #accessing } -MDLCalendar >> currentDate [ - ^ currentDate -] - -{ #category : #accessing } -MDLCalendar >> currentDate: anObject [ - yearsInterval := anObject year - 4 to: anObject year + 4. - currentDate := anObject -] - -{ #category : #'computing weeks' } -MDLCalendar >> daysForWeek: i [ - "Return an array of 7 days for the desired week" - | dayCount firstWeekday previousDayCount previousMonthDays lastDayofPreviousWeek | - i < 1 | (i > 6) ifTrue: [ Error signal: 'Wrong week index' ]. - dayCount := currentDate asMonth daysInMonth . - firstWeekday := Date firstWeekdayOfMonth: currentDate monthIndex year: currentDate year. - previousDayCount := currentDate asMonth previous daysInMonth. - - i = 1 ifTrue: [ - "If this month's first day is the first day in the representation, - the first line is the last week from last month" - firstWeekday = self firstDayOfWeekIndex - ifTrue: [ ^ (previousDayCount - 6 to: previousDayCount) asArray]. - - "Otherwise, its a mix of last month and this month" - previousMonthDays := (firstWeekday - self firstDayOfWeekIndex to: 1 by: -1) collect: [:each | previousDayCount - each + 1]. - ^ previousMonthDays, (1 to: 7 - previousMonthDays size) asArray - ]. - - "Recompute the last day from the previous line" - lastDayofPreviousWeek := (self daysForWeek: i - 1) last. - - "The first week of this month or the first week of next month - begin with the first day of the week " - ((i = 2 and: [ lastDayofPreviousWeek = previousDayCount ]) - or: [ lastDayofPreviousWeek = dayCount ]) - ifTrue: [ ^ (1 to: 7) asArray ]. - - ^ (lastDayofPreviousWeek + 1 to: lastDayofPreviousWeek + 7) collect: - [ :each | - each <= dayCount - ifTrue: [ each ] - ifFalse: [ each - dayCount ] - ] -] - -{ #category : #accessing } -MDLCalendar >> firstDayOfWeekIndex [ - ^ firstDayOfWeekIndex -] - -{ #category : #accessing } -MDLCalendar >> firstDayOfWeekIndex: anInteger [ - firstDayOfWeekIndex := anInteger -] - -{ #category : #accessing } -MDLCalendar >> goToMonth: anIndex [ - | oldIndex | - oldIndex := currentDate monthIndex. - self currentDate: (currentDate addMonths: anIndex - oldIndex) -] - -{ #category : #accessing } -MDLCalendar >> goToYear: aNumber [ - self currentDate: (currentDate addMonths: (aNumber - currentDate year) * 12) -] - -{ #category : #initialization } -MDLCalendar >> initialize [ - super initialize. - self currentDate: Date today. - self firstDayOfWeekIndex: 1 -] - -{ #category : #printing } -MDLCalendar >> printDateForHeader [ - ^ String - streamContents: [ :s | - s - nextPutAll: self currentDate asDateAndTime dayOfWeekAbbreviation; - nextPutAll: ', '; - nextPutAll: self currentDate monthAbbreviation; - space; - print: self currentDate dayOfMonth ] -] - -{ #category : #accessing } -MDLCalendar >> selectNextMonth [ - currentDate := currentDate onNextMonth -] - -{ #category : #accessing } -MDLCalendar >> selectNextYears [ - yearsInterval := yearsInterval + 9 -] - -{ #category : #accessing } -MDLCalendar >> selectPreviousMonth [ - currentDate := currentDate onPreviousMonth -] - -{ #category : #accessing } -MDLCalendar >> selectPreviousYears [ - yearsInterval := yearsInterval - 9 -] - -{ #category : #accessing } -MDLCalendar >> yearsInterval [ - "This will be removed. In the calendar we let the user select the year by displaying year 9 by 9. 4 before the current year, 4 after the current year by default. - - I think this should not be the responsibility of the MDLCalendar but of the MDLCalendarWidget? See https://github.com/DuneSt/MaterialDesignLite/issues/178" - - ^ yearsInterval -] +" +firstDayOfWeekIndex is the index of the first day of the week in the representation, 7 being saturday and 1 sunday +" +Class { + #name : #MDLCalendar, + #superclass : #Object, + #instVars : [ + 'currentDate', + 'firstDayOfWeekIndex', + 'yearsInterval' + ], + #category : 'Material-Design-Lite-Widgets-Calendar' +} + +{ #category : #accessing } +MDLCalendar >> currentDate [ + ^ currentDate +] + +{ #category : #accessing } +MDLCalendar >> currentDate: anObject [ + yearsInterval := anObject year - 4 to: anObject year + 4. + currentDate := anObject +] + +{ #category : #'computing weeks' } +MDLCalendar >> daysForWeek: i [ + "Return an array of 7 days for the desired week" + | dayCount firstWeekday previousDayCount previousMonthDays lastDayofPreviousWeek | + i < 1 | (i > 6) ifTrue: [ Error signal: 'Wrong week index' ]. + dayCount := currentDate asMonth daysInMonth . + firstWeekday := Date firstWeekdayOfMonth: currentDate monthIndex year: currentDate year. + previousDayCount := currentDate asMonth previous daysInMonth. + + i = 1 ifTrue: [ + "If this month's first day is the first day in the representation, + the first line is the last week from last month" + firstWeekday = self firstDayOfWeekIndex + ifTrue: [ ^ (previousDayCount - 6 to: previousDayCount) asArray]. + + "Otherwise, its a mix of last month and this month" + previousMonthDays := (firstWeekday - self firstDayOfWeekIndex to: 1 by: -1) collect: [:each | previousDayCount - each + 1]. + ^ previousMonthDays, (1 to: 7 - previousMonthDays size) asArray + ]. + + "Recompute the last day from the previous line" + lastDayofPreviousWeek := (self daysForWeek: i - 1) last. + + "The first week of this month or the first week of next month + begin with the first day of the week " + ((i = 2 and: [ lastDayofPreviousWeek = previousDayCount ]) + or: [ lastDayofPreviousWeek = dayCount ]) + ifTrue: [ ^ (1 to: 7) asArray ]. + + ^ (lastDayofPreviousWeek + 1 to: lastDayofPreviousWeek + 7) collect: + [ :each | + each <= dayCount + ifTrue: [ each ] + ifFalse: [ each - dayCount ] + ] +] + +{ #category : #accessing } +MDLCalendar >> firstDayOfWeekIndex [ + ^ firstDayOfWeekIndex +] + +{ #category : #accessing } +MDLCalendar >> firstDayOfWeekIndex: anInteger [ + firstDayOfWeekIndex := anInteger +] + +{ #category : #accessing } +MDLCalendar >> goToMonth: anIndex [ + | oldIndex | + oldIndex := currentDate monthIndex. + self currentDate: (currentDate addMonths: anIndex - oldIndex) +] + +{ #category : #accessing } +MDLCalendar >> goToYear: aNumber [ + self currentDate: (currentDate addMonths: (aNumber - currentDate year) * 12) +] + +{ #category : #initialization } +MDLCalendar >> initialize [ + super initialize. + self currentDate: Date today. + self firstDayOfWeekIndex: 1 +] + +{ #category : #printing } +MDLCalendar >> printDateForHeader [ + ^ String + streamContents: [ :s | + s + nextPutAll: self currentDate asDateAndTime dayOfWeekAbbreviation; + nextPutAll: ', '; + nextPutAll: self currentDate monthAbbreviation; + space; + print: self currentDate dayOfMonth ] +] + +{ #category : #accessing } +MDLCalendar >> selectNextMonth [ + currentDate := currentDate onNextMonth +] + +{ #category : #accessing } +MDLCalendar >> selectNextYears [ + yearsInterval := yearsInterval + 9 +] + +{ #category : #accessing } +MDLCalendar >> selectPreviousMonth [ + currentDate := currentDate onPreviousMonth +] + +{ #category : #accessing } +MDLCalendar >> selectPreviousYears [ + yearsInterval := yearsInterval - 9 +] + +{ #category : #accessing } +MDLCalendar >> yearsInterval [ + "This will be removed. In the calendar we let the user select the year by displaying year 9 by 9. 4 before the current year, 4 after the current year by default. + + I think this should not be the responsibility of the MDLCalendar but of the MDLCalendarWidget? See https://github.com/DuneSt/MaterialDesignLite/issues/178" + + ^ yearsInterval +] diff --git a/src/Material-Design-Lite-Widgets/MDLCardActionsWidget.class.st b/src/Material-Design-Lite-Widgets/MDLCardActionsWidget.class.st index be74adbc..c3a43d85 100644 --- a/src/Material-Design-Lite-Widgets/MDLCardActionsWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLCardActionsWidget.class.st @@ -1,44 +1,44 @@ -" -Widget for actions -" -Class { - #name : #MDLCardActionsWidget, - #superclass : #MDLHighLevelWidget, - #instVars : [ - 'componentOrBlocks', - 'bordered' - ], - #category : 'Material-Design-Lite-Widgets-Cards' -} - -{ #category : #adding } -MDLCardActionsWidget >> addComponentOrBlock: aComponentOrBlock [ - componentOrBlocks add: aComponentOrBlock -] - -{ #category : #options } -MDLCardActionsWidget >> beBordered [ - bordered := true -] - -{ #category : #initialization } -MDLCardActionsWidget >> initialize [ - super initialize. - bordered := false. - componentOrBlocks := OrderedCollection new -] - -{ #category : #rendering } -MDLCardActionsWidget >> renderContentOn: html [ - | cardActions | - cardActions := html mdlCardActions. - self addPropertiesToBrush: cardActions. - bordered - ifTrue: [ cardActions border ]. - cardActions - with: [ componentOrBlocks - do: [ :aComponentOrBlock | - aComponentOrBlock isBlock - ifTrue: [ aComponentOrBlock cull: html ] - ifFalse: [ html render: aComponentOrBlock ] ] ] -] +" +Widget for actions +" +Class { + #name : #MDLCardActionsWidget, + #superclass : #MDLHighLevelWidget, + #instVars : [ + 'componentOrBlocks', + 'bordered' + ], + #category : 'Material-Design-Lite-Widgets-Cards' +} + +{ #category : #adding } +MDLCardActionsWidget >> addComponentOrBlock: aComponentOrBlock [ + componentOrBlocks add: aComponentOrBlock +] + +{ #category : #options } +MDLCardActionsWidget >> beBordered [ + bordered := true +] + +{ #category : #initialization } +MDLCardActionsWidget >> initialize [ + super initialize. + bordered := false. + componentOrBlocks := OrderedCollection new +] + +{ #category : #rendering } +MDLCardActionsWidget >> renderContentOn: html [ + | cardActions | + cardActions := html mdlCardActions. + self addPropertiesToBrush: cardActions. + bordered + ifTrue: [ cardActions border ]. + cardActions + with: [ componentOrBlocks + do: [ :aComponentOrBlock | + aComponentOrBlock isBlock + ifTrue: [ aComponentOrBlock cull: html ] + ifFalse: [ html render: aComponentOrBlock ] ] ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLCardMediaWidget.class.st b/src/Material-Design-Lite-Widgets/MDLCardMediaWidget.class.st index dd93c373..20d16c10 100644 --- a/src/Material-Design-Lite-Widgets/MDLCardMediaWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLCardMediaWidget.class.st @@ -1,28 +1,28 @@ -" -I represent a card media widget -" -Class { - #name : #MDLCardMediaWidget, - #superclass : #MDLHighLevelWidget, - #instVars : [ - 'content' - ], - #category : 'Material-Design-Lite-Widgets-Cards' -} - -{ #category : #'instance creation' } -MDLCardMediaWidget class >> newWith: aBlock [ - ^ self new - content: aBlock; - yourself -] - -{ #category : #accessing } -MDLCardMediaWidget >> content: aBlock [ - content := aBlock -] - -{ #category : #rendering } -MDLCardMediaWidget >> renderContentOn: html [ - html mdlCardMedia: [ content value: html ] -] +" +I represent a card media widget +" +Class { + #name : #MDLCardMediaWidget, + #superclass : #MDLHighLevelWidget, + #instVars : [ + 'content' + ], + #category : 'Material-Design-Lite-Widgets-Cards' +} + +{ #category : #'instance creation' } +MDLCardMediaWidget class >> newWith: aBlock [ + ^ self new + content: aBlock; + yourself +] + +{ #category : #accessing } +MDLCardMediaWidget >> content: aBlock [ + content := aBlock +] + +{ #category : #rendering } +MDLCardMediaWidget >> renderContentOn: html [ + html mdlCardMedia: [ content value: html ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLCardTextContainerWidget.class.st b/src/Material-Design-Lite-Widgets/MDLCardTextContainerWidget.class.st index 89b8f986..919670c8 100644 --- a/src/Material-Design-Lite-Widgets/MDLCardTextContainerWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLCardTextContainerWidget.class.st @@ -1,39 +1,39 @@ -" -Widget for text container -" -Class { - #name : #MDLCardTextContainerWidget, - #superclass : #MDLHighLevelWidget, - #instVars : [ - 'content' - ], - #category : 'Material-Design-Lite-Widgets-Cards' -} - -{ #category : #'instance creation' } -MDLCardTextContainerWidget class >> newWithContent: anObject [ - ^ self new - content: anObject; - yourself -] - -{ #category : #'instance creation' } -MDLCardTextContainerWidget class >> newWithContent: anObject class: cssClasses [ - ^ self new - content: anObject; - class: cssClasses; - yourself -] - -{ #category : #accessing } -MDLCardTextContainerWidget >> content: text [ - content := text -] - -{ #category : #rendering } -MDLCardTextContainerWidget >> renderContentOn: html [ - | brush | - brush := html mdlCardTextContainer. - self addPropertiesToBrush: brush. - brush with: content -] +" +Widget for text container +" +Class { + #name : #MDLCardTextContainerWidget, + #superclass : #MDLHighLevelWidget, + #instVars : [ + 'content' + ], + #category : 'Material-Design-Lite-Widgets-Cards' +} + +{ #category : #'instance creation' } +MDLCardTextContainerWidget class >> newWithContent: anObject [ + ^ self new + content: anObject; + yourself +] + +{ #category : #'instance creation' } +MDLCardTextContainerWidget class >> newWithContent: anObject class: cssClasses [ + ^ self new + content: anObject; + class: cssClasses; + yourself +] + +{ #category : #accessing } +MDLCardTextContainerWidget >> content: text [ + content := text +] + +{ #category : #rendering } +MDLCardTextContainerWidget >> renderContentOn: html [ + | brush | + brush := html mdlCardTextContainer. + self addPropertiesToBrush: brush. + brush with: content +] diff --git a/src/Material-Design-Lite-Widgets/MDLCardTitle.class.st b/src/Material-Design-Lite-Widgets/MDLCardTitle.class.st index 0600c612..21f7ce1d 100644 --- a/src/Material-Design-Lite-Widgets/MDLCardTitle.class.st +++ b/src/Material-Design-Lite-Widgets/MDLCardTitle.class.st @@ -1,63 +1,63 @@ -" -I represent a widget for card title -" -Class { - #name : #MDLCardTitle, - #superclass : #MDLHighLevelWidget, - #instVars : [ - 'level', - 'title' - ], - #category : 'Material-Design-Lite-Widgets-Cards' -} - -{ #category : #'instance creation' } -MDLCardTitle class >> newWithTitle: aString level: aNumber [ - ^ self new - title: aString; - level: aNumber; - yourself -] - -{ #category : #'instance creation' } -MDLCardTitle class >> newWithTitle: aString level: aNumber class: cssClasses [ - ^ self new - title: aString; - level: aNumber; - class: cssClasses; - yourself -] - -{ #category : #initialization } -MDLCardTitle >> initialize [ - super initialize. - level := 2. -] - -{ #category : #accessing } -MDLCardTitle >> level [ - ^ level -] - -{ #category : #accessing } -MDLCardTitle >> level: anObject [ - level := anObject -] - -{ #category : #rendering } -MDLCardTitle >> renderContentOn: html [ - | brush | - brush := html mdlCardTitleContainer. - self addPropertiesToBrush: brush. - brush with: [ html mdlCardTitleText: self title level: self level ] -] - -{ #category : #accessing } -MDLCardTitle >> title [ - ^ title -] - -{ #category : #accessing } -MDLCardTitle >> title: anObject [ - title := anObject -] +" +I represent a widget for card title +" +Class { + #name : #MDLCardTitle, + #superclass : #MDLHighLevelWidget, + #instVars : [ + 'level', + 'title' + ], + #category : 'Material-Design-Lite-Widgets-Cards' +} + +{ #category : #'instance creation' } +MDLCardTitle class >> newWithTitle: aString level: aNumber [ + ^ self new + title: aString; + level: aNumber; + yourself +] + +{ #category : #'instance creation' } +MDLCardTitle class >> newWithTitle: aString level: aNumber class: cssClasses [ + ^ self new + title: aString; + level: aNumber; + class: cssClasses; + yourself +] + +{ #category : #initialization } +MDLCardTitle >> initialize [ + super initialize. + level := 2. +] + +{ #category : #accessing } +MDLCardTitle >> level [ + ^ level +] + +{ #category : #accessing } +MDLCardTitle >> level: anObject [ + level := anObject +] + +{ #category : #rendering } +MDLCardTitle >> renderContentOn: html [ + | brush | + brush := html mdlCardTitleContainer. + self addPropertiesToBrush: brush. + brush with: [ html mdlCardTitleText: self title level: self level ] +] + +{ #category : #accessing } +MDLCardTitle >> title [ + ^ title +] + +{ #category : #accessing } +MDLCardTitle >> title: anObject [ + title := anObject +] diff --git a/src/Material-Design-Lite-Widgets/MDLCardWidget.class.st b/src/Material-Design-Lite-Widgets/MDLCardWidget.class.st index 2cac3075..8038e73f 100644 --- a/src/Material-Design-Lite-Widgets/MDLCardWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLCardWidget.class.st @@ -1,146 +1,146 @@ -" -High level widget to render a card -" -Class { - #name : #MDLCardWidget, - #superclass : #MDLHighLevelWidget, - #instVars : [ - 'componentOrBlocks', - 'cardActions' - ], - #category : 'Material-Design-Lite-Widgets-Cards' -} - -{ #category : #adding } -MDLCardWidget >> accentColorTitle: aString [ - self accentColorTitle: aString class: '' -] - -{ #category : #adding } -MDLCardWidget >> accentColorTitle: aString class: anotherString [ - | classes | - classes := String - streamContents: [ :stream | - stream - nextPutAll: 'mdl-color--accent'; - space; - nextPutAll: 'mdl-color-text--accent-contrast'. - anotherString - ifNotEmpty: [ :string | - stream - space; - nextPutAll: string ] ]. - self title: aString class: classes -] - -{ #category : #options } -MDLCardWidget >> actionsBordered [ - self cardActions beBordered -] - -{ #category : #adding } -MDLCardWidget >> addAction: aComponentOrBlock [ - self cardActions addComponentOrBlock: aComponentOrBlock -] - -{ #category : #adding } -MDLCardWidget >> addComponentOrBlock: aComponentOrBlock [ - componentOrBlocks add: aComponentOrBlock -] - -{ #category : #adding } -MDLCardWidget >> addMedia: aBlock [ - self addComponentOrBlock: (MDLCardMediaWidget newWith: aBlock) -] - -{ #category : #adding } -MDLCardWidget >> addTextContainer: aString [ - self addComponentOrBlock: (MDLCardTextContainerWidget newWithContent: aString) -] - -{ #category : #adding } -MDLCardWidget >> addTextContainer: anObject class: cssClasses [ - self - addComponentOrBlock: (MDLCardTextContainerWidget newWithContent: anObject class: cssClasses) -] - -{ #category : #accessing } -MDLCardWidget >> cardActions [ - ^ cardActions - ifNil: [ cardActions := MDLCardActionsWidget new. - self addComponentOrBlock: cardActions. - ^ cardActions ] -] - -{ #category : #initialization } -MDLCardWidget >> initialize [ - super initialize. - componentOrBlocks := OrderedCollection new. - self class: 'mdl-card-widget' -] - -{ #category : #adding } -MDLCardWidget >> primaryColorTitle: aString [ - self primaryColorTitle: aString class: '' -] - -{ #category : #adding } -MDLCardWidget >> primaryColorTitle: aString class: anotherString [ - | classes | - classes := String - streamContents: [ :stream | - stream - nextPutAll: 'mdl-color--primary'; - space; - nextPutAll: 'mdl-color-text--primary-contrast'. - anotherString - ifNotEmpty: [ :string | - stream - space; - nextPutAll: string ] ]. - self title: aString class: classes -] - -{ #category : #rendering } -MDLCardWidget >> renderContentOn: html [ - | card | - card := html mdlCard. - self addPropertiesToBrush: card. - card with: [ self renderInnerWidgetsOn: html ] -] - -{ #category : #rendering } -MDLCardWidget >> renderInnerWidgetsOn: html [ - componentOrBlocks - do: [ :aComponentOrBlock | - aComponentOrBlock isBlock - ifTrue: [ aComponentOrBlock cull: html ] - ifFalse: [ html render: aComponentOrBlock ] ] -] - -{ #category : #accessing } -MDLCardWidget >> shadow: aNumber [ - "aNumber must be between 2 and 24" - - self propertiesAt: #shadow: put: (Array with: aNumber) -] - -{ #category : #adding } -MDLCardWidget >> title: aString [ - self title: aString level: 2 -] - -{ #category : #adding } -MDLCardWidget >> title: aString class: cssClasses [ - self title: aString level: 2 class: cssClasses -] - -{ #category : #adding } -MDLCardWidget >> title: aString level: aNumber [ - self title: aString level: aNumber class: '' -] - -{ #category : #adding } -MDLCardWidget >> title: aString level: aNumber class: cssClasses [ - self addComponentOrBlock: (MDLCardTitle newWithTitle: aString level: aNumber class: cssClasses) -] +" +High level widget to render a card +" +Class { + #name : #MDLCardWidget, + #superclass : #MDLHighLevelWidget, + #instVars : [ + 'componentOrBlocks', + 'cardActions' + ], + #category : 'Material-Design-Lite-Widgets-Cards' +} + +{ #category : #adding } +MDLCardWidget >> accentColorTitle: aString [ + self accentColorTitle: aString class: '' +] + +{ #category : #adding } +MDLCardWidget >> accentColorTitle: aString class: anotherString [ + | classes | + classes := String + streamContents: [ :stream | + stream + nextPutAll: 'mdl-color--accent'; + space; + nextPutAll: 'mdl-color-text--accent-contrast'. + anotherString + ifNotEmpty: [ :string | + stream + space; + nextPutAll: string ] ]. + self title: aString class: classes +] + +{ #category : #options } +MDLCardWidget >> actionsBordered [ + self cardActions beBordered +] + +{ #category : #adding } +MDLCardWidget >> addAction: aComponentOrBlock [ + self cardActions addComponentOrBlock: aComponentOrBlock +] + +{ #category : #adding } +MDLCardWidget >> addComponentOrBlock: aComponentOrBlock [ + componentOrBlocks add: aComponentOrBlock +] + +{ #category : #adding } +MDLCardWidget >> addMedia: aBlock [ + self addComponentOrBlock: (MDLCardMediaWidget newWith: aBlock) +] + +{ #category : #adding } +MDLCardWidget >> addTextContainer: aString [ + self addComponentOrBlock: (MDLCardTextContainerWidget newWithContent: aString) +] + +{ #category : #adding } +MDLCardWidget >> addTextContainer: anObject class: cssClasses [ + self + addComponentOrBlock: (MDLCardTextContainerWidget newWithContent: anObject class: cssClasses) +] + +{ #category : #accessing } +MDLCardWidget >> cardActions [ + ^ cardActions + ifNil: [ cardActions := MDLCardActionsWidget new. + self addComponentOrBlock: cardActions. + ^ cardActions ] +] + +{ #category : #initialization } +MDLCardWidget >> initialize [ + super initialize. + componentOrBlocks := OrderedCollection new. + self class: 'mdl-card-widget' +] + +{ #category : #adding } +MDLCardWidget >> primaryColorTitle: aString [ + self primaryColorTitle: aString class: '' +] + +{ #category : #adding } +MDLCardWidget >> primaryColorTitle: aString class: anotherString [ + | classes | + classes := String + streamContents: [ :stream | + stream + nextPutAll: 'mdl-color--primary'; + space; + nextPutAll: 'mdl-color-text--primary-contrast'. + anotherString + ifNotEmpty: [ :string | + stream + space; + nextPutAll: string ] ]. + self title: aString class: classes +] + +{ #category : #rendering } +MDLCardWidget >> renderContentOn: html [ + | card | + card := html mdlCard. + self addPropertiesToBrush: card. + card with: [ self renderInnerWidgetsOn: html ] +] + +{ #category : #rendering } +MDLCardWidget >> renderInnerWidgetsOn: html [ + componentOrBlocks + do: [ :aComponentOrBlock | + aComponentOrBlock isBlock + ifTrue: [ aComponentOrBlock cull: html ] + ifFalse: [ html render: aComponentOrBlock ] ] +] + +{ #category : #accessing } +MDLCardWidget >> shadow: aNumber [ + "aNumber must be between 2 and 24" + + self propertiesAt: #shadow: put: (Array with: aNumber) +] + +{ #category : #adding } +MDLCardWidget >> title: aString [ + self title: aString level: 2 +] + +{ #category : #adding } +MDLCardWidget >> title: aString class: cssClasses [ + self title: aString level: 2 class: cssClasses +] + +{ #category : #adding } +MDLCardWidget >> title: aString level: aNumber [ + self title: aString level: aNumber class: '' +] + +{ #category : #adding } +MDLCardWidget >> title: aString level: aNumber class: cssClasses [ + self addComponentOrBlock: (MDLCardTitle newWithTitle: aString level: aNumber class: cssClasses) +] diff --git a/src/Material-Design-Lite-Widgets/MDLContentCenterer.class.st b/src/Material-Design-Lite-Widgets/MDLContentCenterer.class.st index 9f6b2866..54490a2f 100644 --- a/src/Material-Design-Lite-Widgets/MDLContentCenterer.class.st +++ b/src/Material-Design-Lite-Widgets/MDLContentCenterer.class.st @@ -1,70 +1,70 @@ -" -Just a widget that allow to center a component and specify its size -" -Class { - #name : #MDLContentCenterer, - #superclass : #WAComponent, - #instVars : [ - 'component', - 'desktopSize', - 'tabletSize', - 'phoneSize' - ], - #category : 'Material-Design-Lite-Widgets' -} - -{ #category : #accessing } -MDLContentCenterer >> component [ - ^ component -] - -{ #category : #accessing } -MDLContentCenterer >> component: anObject [ - component := anObject -] - -{ #category : #accessing } -MDLContentCenterer >> desktopSize [ - ^ desktopSize -] - -{ #category : #accessing } -MDLContentCenterer >> desktopSize: anObject [ - desktopSize := anObject -] - -{ #category : #accessing } -MDLContentCenterer >> phoneSize [ - ^ phoneSize -] - -{ #category : #accessing } -MDLContentCenterer >> phoneSize: anObject [ - phoneSize := anObject -] - -{ #category : #rendering } -MDLContentCenterer >> renderContentOn: html [ - html mdlGrid: [ - html mdlLayoutSpacer. - html mdlCellDesktop: desktopSize tablet: tabletSize phone: phoneSize with: component. - html mdlLayoutSpacer ]. - super renderContentOn: html -] - -{ #category : #accessing } -MDLContentCenterer >> size: anObject [ - self desktopSize: anObject. - self phoneSize: anObject. - self tabletSize: anObject -] - -{ #category : #accessing } -MDLContentCenterer >> tabletSize [ - ^ tabletSize -] - -{ #category : #accessing } -MDLContentCenterer >> tabletSize: anObject [ - tabletSize := anObject -] +" +Just a widget that allow to center a component and specify its size +" +Class { + #name : #MDLContentCenterer, + #superclass : #WAComponent, + #instVars : [ + 'component', + 'desktopSize', + 'tabletSize', + 'phoneSize' + ], + #category : 'Material-Design-Lite-Widgets' +} + +{ #category : #accessing } +MDLContentCenterer >> component [ + ^ component +] + +{ #category : #accessing } +MDLContentCenterer >> component: anObject [ + component := anObject +] + +{ #category : #accessing } +MDLContentCenterer >> desktopSize [ + ^ desktopSize +] + +{ #category : #accessing } +MDLContentCenterer >> desktopSize: anObject [ + desktopSize := anObject +] + +{ #category : #accessing } +MDLContentCenterer >> phoneSize [ + ^ phoneSize +] + +{ #category : #accessing } +MDLContentCenterer >> phoneSize: anObject [ + phoneSize := anObject +] + +{ #category : #rendering } +MDLContentCenterer >> renderContentOn: html [ + html mdlGrid: [ + html mdlLayoutSpacer. + html mdlCellDesktop: desktopSize tablet: tabletSize phone: phoneSize with: component. + html mdlLayoutSpacer ]. + super renderContentOn: html +] + +{ #category : #accessing } +MDLContentCenterer >> size: anObject [ + self desktopSize: anObject. + self phoneSize: anObject. + self tabletSize: anObject +] + +{ #category : #accessing } +MDLContentCenterer >> tabletSize [ + ^ tabletSize +] + +{ #category : #accessing } +MDLContentCenterer >> tabletSize: anObject [ + tabletSize := anObject +] diff --git a/src/Material-Design-Lite-Widgets/MDLDatePicker.class.st b/src/Material-Design-Lite-Widgets/MDLDatePicker.class.st index f22e7e9b..c3e05c72 100644 --- a/src/Material-Design-Lite-Widgets/MDLDatePicker.class.st +++ b/src/Material-Design-Lite-Widgets/MDLDatePicker.class.st @@ -1,26 +1,26 @@ -" -I am a date picker embebded in a MDLCard for a better display. -" -Class { - #name : #MDLDatePicker, - #superclass : #MDLFlatDatePicker, - #category : #'Material-Design-Lite-Widgets-Calendar' -} - -{ #category : #accessing } -MDLDatePicker >> containerClass [ - ^ 'mdl-calendar-card' -] - -{ #category : #rendering } -MDLDatePicker >> renderCalendarOn: html [ - html - render: - (MDLCardWidget new - shadow: 2; - class: 'mdl-calendar-widget'; - addProperties: properties; - primaryColorTitle: self calendar printDateForHeader; - addTextContainer: [ self renderCalendarContentOn: html ]; - yourself) -] +" +I am a date picker embebded in a MDLCard for a better display. +" +Class { + #name : #MDLDatePicker, + #superclass : #MDLFlatDatePicker, + #category : #'Material-Design-Lite-Widgets-Calendar' +} + +{ #category : #accessing } +MDLDatePicker >> containerClass [ + ^ 'mdl-calendar-card' +] + +{ #category : #rendering } +MDLDatePicker >> renderCalendarOn: html [ + html + render: + (MDLCardWidget new + shadow: 2; + class: 'mdl-calendar-widget'; + addProperties: properties; + primaryColorTitle: self calendar printDateForHeader; + addTextContainer: [ self renderCalendarContentOn: html ]; + yourself) +] diff --git a/src/Material-Design-Lite-Widgets/MDLDialogWidget.class.st b/src/Material-Design-Lite-Widgets/MDLDialogWidget.class.st index 181104bd..874d2478 100644 --- a/src/Material-Design-Lite-Widgets/MDLDialogWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLDialogWidget.class.st @@ -1,176 +1,176 @@ -" -I represent a dialog widget -" -Class { - #name : #MDLDialogWidget, - #superclass : #MDLWidget, - #instVars : [ - 'title', - 'content', - 'actions', - 'buttonName', - 'closeButtonName', - 'buttonBrush', - 'dialogBrush' - ], - #category : 'Material-Design-Lite-Widgets-Dialog' -} - -{ #category : #'instance creation' } -MDLDialogWidget class >> content: aBlock actions: aSecondBlock buttonName: aString [ - ^ (self content: aBlock buttonName: aString) - actions: aSecondBlock; - yourself -] - -{ #category : #'instance creation' } -MDLDialogWidget class >> content: aBlock actions: aSecondBlock buttonName: aString closeButtonName: aSecondString [ - ^ (self new content: aBlock actions: aSecondBlock buttonName: aString) - closeButtonName: aSecondString; - yourself -] - -{ #category : #'instance creation' } -MDLDialogWidget class >> content: aBlock actions: aSecondBlock closeButtonName: aString [ - ^ (self content: aBlock buttonName: aString) - closeButtonName: aSecondBlock; - yourself -] - -{ #category : #'instance creation' } -MDLDialogWidget class >> content: aBlock buttonName: aString [ - ^ self new - content: aBlock; - buttonName: aString; - yourself -] - -{ #category : #'instance creation' } -MDLDialogWidget class >> title: aString content: aBlock actions: aSecondBlock buttonName: aSecondString [ - ^ (self content: aBlock actions: aSecondBlock buttonName: aSecondString) - title: aString; - yourself -] - -{ #category : #'instance creation' } -MDLDialogWidget class >> title: aString content: aBlock actions: aSecondBlock buttonName: aSecondString closeButtonName: aThirdString [ - ^ (self title: aString content: aBlock actions: aSecondBlock buttonName: aSecondString) - closeButtonName: aThirdString; - yourself -] - -{ #category : #'instance creation' } -MDLDialogWidget class >> title: aString content: aBlock buttonName: aSecondString [ - ^ (self content: aBlock buttonName: aSecondString) - title: aString; - yourself -] - -{ #category : #'instance creation' } -MDLDialogWidget class >> title: aString content: aBlock buttonName: aSecondString closeButtonName: aThirdString [ - ^ (self title: aString content: aBlock buttonName: aSecondString) - closeButtonName: aThirdString; - yourself -] - -{ #category : #accessing } -MDLDialogWidget >> actions [ - ^ actions -] - -{ #category : #accessing } -MDLDialogWidget >> actions: anObject [ - actions := anObject -] - -{ #category : #accessing } -MDLDialogWidget >> buttonBrush [ - ^ buttonBrush -] - -{ #category : #accessing } -MDLDialogWidget >> buttonBrush: anObject [ - buttonBrush := anObject -] - -{ #category : #accessing } -MDLDialogWidget >> buttonName [ - ^ buttonName -] - -{ #category : #accessing } -MDLDialogWidget >> buttonName: anObject [ - buttonName := anObject -] - -{ #category : #accessing } -MDLDialogWidget >> closeButtonName [ - ^ closeButtonName -] - -{ #category : #accessing } -MDLDialogWidget >> closeButtonName: anObject [ - closeButtonName := anObject -] - -{ #category : #accessing } -MDLDialogWidget >> content [ - ^ content -] - -{ #category : #accessing } -MDLDialogWidget >> content: anObject [ - content := anObject -] - -{ #category : #accessing } -MDLDialogWidget >> dialogBrush [ - ^ dialogBrush -] - -{ #category : #accessing } -MDLDialogWidget >> dialogBrush: anObject [ - dialogBrush := anObject -] - -{ #category : #initialization } -MDLDialogWidget >> initialize [ - super initialize. - closeButtonName := 'Close'. - buttonBrush := MDLButton new. - dialogBrush := MDLDialog new -] - -{ #category : #rendering } -MDLDialogWidget >> renderContentOn: html [ - | closeButtonId | - self ensureId: html. - (html brush: self buttonBrush) - id: self id; - bePush; - raised; - rippleEffect; - with: self buttonName. - (html brush: self dialogBrush) - id: html nextId; - openButtonId: self id; - closeButtonId: (closeButtonId := html nextId); - with: [ self title ifNotNil: [ :t | html mdlDialogTitle: t ]. - html mdlDialogContent: self content. - html - mdlDialogActions: [ self actions ifNotNil: [ :acts | html render: acts ]. - html mdlButton - id: closeButtonId; - bePush; - with: self closeButtonName ] ] -] - -{ #category : #accessing } -MDLDialogWidget >> title [ - ^ title -] - -{ #category : #accessing } -MDLDialogWidget >> title: anObject [ - title := anObject -] +" +I represent a dialog widget +" +Class { + #name : #MDLDialogWidget, + #superclass : #MDLWidget, + #instVars : [ + 'title', + 'content', + 'actions', + 'buttonName', + 'closeButtonName', + 'buttonBrush', + 'dialogBrush' + ], + #category : 'Material-Design-Lite-Widgets-Dialog' +} + +{ #category : #'instance creation' } +MDLDialogWidget class >> content: aBlock actions: aSecondBlock buttonName: aString [ + ^ (self content: aBlock buttonName: aString) + actions: aSecondBlock; + yourself +] + +{ #category : #'instance creation' } +MDLDialogWidget class >> content: aBlock actions: aSecondBlock buttonName: aString closeButtonName: aSecondString [ + ^ (self new content: aBlock actions: aSecondBlock buttonName: aString) + closeButtonName: aSecondString; + yourself +] + +{ #category : #'instance creation' } +MDLDialogWidget class >> content: aBlock actions: aSecondBlock closeButtonName: aString [ + ^ (self content: aBlock buttonName: aString) + closeButtonName: aSecondBlock; + yourself +] + +{ #category : #'instance creation' } +MDLDialogWidget class >> content: aBlock buttonName: aString [ + ^ self new + content: aBlock; + buttonName: aString; + yourself +] + +{ #category : #'instance creation' } +MDLDialogWidget class >> title: aString content: aBlock actions: aSecondBlock buttonName: aSecondString [ + ^ (self content: aBlock actions: aSecondBlock buttonName: aSecondString) + title: aString; + yourself +] + +{ #category : #'instance creation' } +MDLDialogWidget class >> title: aString content: aBlock actions: aSecondBlock buttonName: aSecondString closeButtonName: aThirdString [ + ^ (self title: aString content: aBlock actions: aSecondBlock buttonName: aSecondString) + closeButtonName: aThirdString; + yourself +] + +{ #category : #'instance creation' } +MDLDialogWidget class >> title: aString content: aBlock buttonName: aSecondString [ + ^ (self content: aBlock buttonName: aSecondString) + title: aString; + yourself +] + +{ #category : #'instance creation' } +MDLDialogWidget class >> title: aString content: aBlock buttonName: aSecondString closeButtonName: aThirdString [ + ^ (self title: aString content: aBlock buttonName: aSecondString) + closeButtonName: aThirdString; + yourself +] + +{ #category : #accessing } +MDLDialogWidget >> actions [ + ^ actions +] + +{ #category : #accessing } +MDLDialogWidget >> actions: anObject [ + actions := anObject +] + +{ #category : #accessing } +MDLDialogWidget >> buttonBrush [ + ^ buttonBrush +] + +{ #category : #accessing } +MDLDialogWidget >> buttonBrush: anObject [ + buttonBrush := anObject +] + +{ #category : #accessing } +MDLDialogWidget >> buttonName [ + ^ buttonName +] + +{ #category : #accessing } +MDLDialogWidget >> buttonName: anObject [ + buttonName := anObject +] + +{ #category : #accessing } +MDLDialogWidget >> closeButtonName [ + ^ closeButtonName +] + +{ #category : #accessing } +MDLDialogWidget >> closeButtonName: anObject [ + closeButtonName := anObject +] + +{ #category : #accessing } +MDLDialogWidget >> content [ + ^ content +] + +{ #category : #accessing } +MDLDialogWidget >> content: anObject [ + content := anObject +] + +{ #category : #accessing } +MDLDialogWidget >> dialogBrush [ + ^ dialogBrush +] + +{ #category : #accessing } +MDLDialogWidget >> dialogBrush: anObject [ + dialogBrush := anObject +] + +{ #category : #initialization } +MDLDialogWidget >> initialize [ + super initialize. + closeButtonName := 'Close'. + buttonBrush := MDLButton new. + dialogBrush := MDLDialog new +] + +{ #category : #rendering } +MDLDialogWidget >> renderContentOn: html [ + | closeButtonId | + self ensureId: html. + (html brush: self buttonBrush) + id: self id; + bePush; + raised; + rippleEffect; + with: self buttonName. + (html brush: self dialogBrush) + id: html nextId; + openButtonId: self id; + closeButtonId: (closeButtonId := html nextId); + with: [ self title ifNotNil: [ :t | html mdlDialogTitle: t ]. + html mdlDialogContent: self content. + html + mdlDialogActions: [ self actions ifNotNil: [ :acts | html render: acts ]. + html mdlButton + id: closeButtonId; + bePush; + with: self closeButtonName ] ] +] + +{ #category : #accessing } +MDLDialogWidget >> title [ + ^ title +] + +{ #category : #accessing } +MDLDialogWidget >> title: anObject [ + title := anObject +] diff --git a/src/Material-Design-Lite-Widgets/MDLExpansionPanel.class.st b/src/Material-Design-Lite-Widgets/MDLExpansionPanel.class.st index 2ee66c87..ee389f54 100644 --- a/src/Material-Design-Lite-Widgets/MDLExpansionPanel.class.st +++ b/src/Material-Design-Lite-Widgets/MDLExpansionPanel.class.st @@ -1,162 +1,162 @@ -" -I am an expansion panel. - -Basically, I have a title, a description, an icon and I can be folded or expanded to show additional information. - -Though I provide default icons, one can set a different icon for when I am fold (#foldIcon:) or when I am expanded (#expandIcon:). - -One can set my initial state via #isExpanded: or #isFolded:. - -I can use different expansion strategies via #useDisplayNoneExpansionStrategy, #useAjaxExpansionStrategy. #useLazyExpansionStrategy. -See MDLExpansionStrategy subclasses for documentation about them. -My default strategy is MDLDisplayNoneStrategy. -" -Class { - #name : #MDLExpansionPanel, - #superclass : #MDLWidget, - #instVars : [ - 'title', - 'descriptions', - 'expandedBlock', - 'isExpanded', - 'shadow', - 'expansionStrategy' - ], - #category : #'Material-Design-Lite-Widgets-Expansion' -} - -{ #category : #accessing } -MDLExpansionPanel >> description: anObject [ - self descriptions: { anObject } -] - -{ #category : #accessing } -MDLExpansionPanel >> descriptions [ - ^ descriptions -] - -{ #category : #accessing } -MDLExpansionPanel >> descriptions: aCollection [ - descriptions := aCollection -] - -{ #category : #accessing } -MDLExpansionPanel >> expandedBlock [ - ^ expandedBlock -] - -{ #category : #accessing } -MDLExpansionPanel >> expandedBlock: anObject [ - expandedBlock := anObject -] - -{ #category : #accessing } -MDLExpansionPanel >> expansionStrategy [ - ^ expansionStrategy -] - -{ #category : #accessing } -MDLExpansionPanel >> expansionStrategy: anObject [ - expansionStrategy := anObject -] - -{ #category : #initialization } -MDLExpansionPanel >> initialize [ - super initialize. - self - title: ''; - description: ''; - shadow: 2; - isExpanded: false; - useHideExpansionStrategy -] - -{ #category : #accessing } -MDLExpansionPanel >> isExpanded [ - ^ isExpanded -] - -{ #category : #accessing } -MDLExpansionPanel >> isExpanded: anObject [ - isExpanded := anObject -] - -{ #category : #rendering } -MDLExpansionPanel >> isFolded [ - ^ self isExpanded not -] - -{ #category : #accessing } -MDLExpansionPanel >> isFolded: aBoolean [ - self isExpanded: aBoolean not -] - -{ #category : #rendering } -MDLExpansionPanel >> renderContentOn: html [ - self ensureId: html. - html mdlExpansionPanel - id: self id; - shadow: self shadow; - foldIf: self isFolded; - with: [ self renderExpansionPanelHeaderOn: html. - html mdlExpansionPanelContent: [ self renderExpansionPanelContentOn: html ] ] -] - -{ #category : #rendering } -MDLExpansionPanel >> renderExpansionPanelContentOn: html [ - self expansionStrategy renderExpansionPanel: self contentOn: html -] - -{ #category : #rendering } -MDLExpansionPanel >> renderExpansionPanelHeaderOn: html [ - | header | - header := html mdlExpansionPanelHeader - toggleExpansionOnClick; - yourself. - self expansionStrategy customize: header in: self on: html. - header - with: [ html mdlExpansionPanelHeaderTitle: self title. - self descriptions do: [ :description | html mdlExpansionPanelHeaderDescription: description ]. - html mdlExpansionPanelHeaderIcon ] -] - -{ #category : #accessing } -MDLExpansionPanel >> shadow [ - ^ shadow -] - -{ #category : #accessing } -MDLExpansionPanel >> shadow: anObject [ - shadow := anObject -] - -{ #category : #accessing } -MDLExpansionPanel >> title [ - ^ title -] - -{ #category : #accessing } -MDLExpansionPanel >> title: anObject [ - title := anObject -] - -{ #category : #toggling } -MDLExpansionPanel >> toggleExpansion [ - self isExpanded: self isExpanded not -] - -{ #category : #configuring } -MDLExpansionPanel >> useAjaxExpansionStrategy [ - self expansionStrategy: MDLAjaxExpansionStrategy new -] - -{ #category : #configuring } -MDLExpansionPanel >> useHideExpansionStrategy [ - "Default strategy." - self expansionStrategy: MDLHideExpansionStrategy new -] - -{ #category : #configuring } -MDLExpansionPanel >> useLazyExpansionStrategy [ - self expansionStrategy: MDLLazyExpansionStrategy new -] +" +I am an expansion panel. + +Basically, I have a title, a description, an icon and I can be folded or expanded to show additional information. + +Though I provide default icons, one can set a different icon for when I am fold (#foldIcon:) or when I am expanded (#expandIcon:). + +One can set my initial state via #isExpanded: or #isFolded:. + +I can use different expansion strategies via #useDisplayNoneExpansionStrategy, #useAjaxExpansionStrategy. #useLazyExpansionStrategy. +See MDLExpansionStrategy subclasses for documentation about them. +My default strategy is MDLDisplayNoneStrategy. +" +Class { + #name : #MDLExpansionPanel, + #superclass : #MDLWidget, + #instVars : [ + 'title', + 'descriptions', + 'expandedBlock', + 'isExpanded', + 'shadow', + 'expansionStrategy' + ], + #category : #'Material-Design-Lite-Widgets-Expansion' +} + +{ #category : #accessing } +MDLExpansionPanel >> description: anObject [ + self descriptions: { anObject } +] + +{ #category : #accessing } +MDLExpansionPanel >> descriptions [ + ^ descriptions +] + +{ #category : #accessing } +MDLExpansionPanel >> descriptions: aCollection [ + descriptions := aCollection +] + +{ #category : #accessing } +MDLExpansionPanel >> expandedBlock [ + ^ expandedBlock +] + +{ #category : #accessing } +MDLExpansionPanel >> expandedBlock: anObject [ + expandedBlock := anObject +] + +{ #category : #accessing } +MDLExpansionPanel >> expansionStrategy [ + ^ expansionStrategy +] + +{ #category : #accessing } +MDLExpansionPanel >> expansionStrategy: anObject [ + expansionStrategy := anObject +] + +{ #category : #initialization } +MDLExpansionPanel >> initialize [ + super initialize. + self + title: ''; + description: ''; + shadow: 2; + isExpanded: false; + useHideExpansionStrategy +] + +{ #category : #accessing } +MDLExpansionPanel >> isExpanded [ + ^ isExpanded +] + +{ #category : #accessing } +MDLExpansionPanel >> isExpanded: anObject [ + isExpanded := anObject +] + +{ #category : #rendering } +MDLExpansionPanel >> isFolded [ + ^ self isExpanded not +] + +{ #category : #accessing } +MDLExpansionPanel >> isFolded: aBoolean [ + self isExpanded: aBoolean not +] + +{ #category : #rendering } +MDLExpansionPanel >> renderContentOn: html [ + self ensureId: html. + html mdlExpansionPanel + id: self id; + shadow: self shadow; + foldIf: self isFolded; + with: [ self renderExpansionPanelHeaderOn: html. + html mdlExpansionPanelContent: [ self renderExpansionPanelContentOn: html ] ] +] + +{ #category : #rendering } +MDLExpansionPanel >> renderExpansionPanelContentOn: html [ + self expansionStrategy renderExpansionPanel: self contentOn: html +] + +{ #category : #rendering } +MDLExpansionPanel >> renderExpansionPanelHeaderOn: html [ + | header | + header := html mdlExpansionPanelHeader + toggleExpansionOnClick; + yourself. + self expansionStrategy customize: header in: self on: html. + header + with: [ html mdlExpansionPanelHeaderTitle: self title. + self descriptions do: [ :description | html mdlExpansionPanelHeaderDescription: description ]. + html mdlExpansionPanelHeaderIcon ] +] + +{ #category : #accessing } +MDLExpansionPanel >> shadow [ + ^ shadow +] + +{ #category : #accessing } +MDLExpansionPanel >> shadow: anObject [ + shadow := anObject +] + +{ #category : #accessing } +MDLExpansionPanel >> title [ + ^ title +] + +{ #category : #accessing } +MDLExpansionPanel >> title: anObject [ + title := anObject +] + +{ #category : #toggling } +MDLExpansionPanel >> toggleExpansion [ + self isExpanded: self isExpanded not +] + +{ #category : #configuring } +MDLExpansionPanel >> useAjaxExpansionStrategy [ + self expansionStrategy: MDLAjaxExpansionStrategy new +] + +{ #category : #configuring } +MDLExpansionPanel >> useHideExpansionStrategy [ + "Default strategy." + self expansionStrategy: MDLHideExpansionStrategy new +] + +{ #category : #configuring } +MDLExpansionPanel >> useLazyExpansionStrategy [ + self expansionStrategy: MDLLazyExpansionStrategy new +] diff --git a/src/Material-Design-Lite-Widgets/MDLExpansionStrategy.class.st b/src/Material-Design-Lite-Widgets/MDLExpansionStrategy.class.st index 1f4e7d90..20f70b0b 100644 --- a/src/Material-Design-Lite-Widgets/MDLExpansionStrategy.class.st +++ b/src/Material-Design-Lite-Widgets/MDLExpansionStrategy.class.st @@ -1,23 +1,23 @@ -" -I am an abstract expansion strategy, I define the minimal API such strategy should implement. -" -Class { - #name : #MDLExpansionStrategy, - #superclass : #Object, - #category : #'Material-Design-Lite-Widgets-Expansion' -} - -{ #category : #javascript } -MDLExpansionStrategy >> customize: anExpansionPanelHeader in: anExpansionPanel on: html [ - ^ self subclassResponsibility -] - -{ #category : #testing } -MDLExpansionStrategy >> isAjaxExpansionStrategy [ - ^ false -] - -{ #category : #rendering } -MDLExpansionStrategy >> renderExpansionPanel: anExpansionPanel contentOn: html [ - self subclassResponsibility -] +" +I am an abstract expansion strategy, I define the minimal API such strategy should implement. +" +Class { + #name : #MDLExpansionStrategy, + #superclass : #Object, + #category : #'Material-Design-Lite-Widgets-Expansion' +} + +{ #category : #javascript } +MDLExpansionStrategy >> customize: anExpansionPanelHeader in: anExpansionPanel on: html [ + ^ self subclassResponsibility +] + +{ #category : #testing } +MDLExpansionStrategy >> isAjaxExpansionStrategy [ + ^ false +] + +{ #category : #rendering } +MDLExpansionStrategy >> renderExpansionPanel: anExpansionPanel contentOn: html [ + self subclassResponsibility +] diff --git a/src/Material-Design-Lite-Widgets/MDLFlatDatePicker.class.st b/src/Material-Design-Lite-Widgets/MDLFlatDatePicker.class.st index c319e367..1996fd95 100644 --- a/src/Material-Design-Lite-Widgets/MDLFlatDatePicker.class.st +++ b/src/Material-Design-Lite-Widgets/MDLFlatDatePicker.class.st @@ -1,336 +1,336 @@ -" -I am a component displaying a calendar to let the user pick a date. -" -Class { - #name : #MDLFlatDatePicker, - #superclass : #MDLHighLevelWidget, - #instVars : [ - 'daysList', - 'calendar', - 'callback', - 'onCompleteScript' - ], - #category : #'Material-Design-Lite-Widgets-Calendar' -} - -{ #category : #accessing } -MDLFlatDatePicker >> calendar [ - ^ calendar -] - -{ #category : #accessing } -MDLFlatDatePicker >> calendar: anObject [ - calendar := anObject -] - -{ #category : #accessing } -MDLFlatDatePicker >> callback: aOneArgBlock [ - aOneArgBlock argumentCount ~= 1 - ifTrue: [ ^ self error: '1 argument expected' ]. - callback := aOneArgBlock -] - -{ #category : #accessing } -MDLFlatDatePicker >> containerClass [ - ^ 'mdl-calendar' -] - -{ #category : #accessing } -MDLFlatDatePicker >> currentDate [ - ^ self calendar currentDate -] - -{ #category : #accessing } -MDLFlatDatePicker >> currentDate: aDate [ - self calendar currentDate: aDate -] - -{ #category : #accessing } -MDLFlatDatePicker >> daysList [ - ^ daysList -] - -{ #category : #'private-rendering' } -MDLFlatDatePicker >> displayDate: aDate on: html [ - html mdlButton - class: 'mdl-color-text--primary' if: (self isTodayAndNotSelected: aDate); - class: 'mdl-color-text--primary-contrast mdl-color--primary' if: (self selectedDateIs: aDate); - class: 'disabled' if: (self isInCurrentMonth: aDate) not; - rippleEffect; - icon; - onClick: (self jsUpdateDate: aDate on: html); - with: aDate dayOfMonth greaseString -] - -{ #category : #private } -MDLFlatDatePicker >> goToMonth: anObject [ - calendar goToMonth: anObject -] - -{ #category : #private } -MDLFlatDatePicker >> goToNextMonth [ - self calendar selectNextMonth -] - -{ #category : #private } -MDLFlatDatePicker >> goToNextYears [ - self calendar selectNextYears -] - -{ #category : #private } -MDLFlatDatePicker >> goToPreviousMonth [ - self calendar selectPreviousMonth -] - -{ #category : #private } -MDLFlatDatePicker >> goToPreviousYears [ - self calendar selectPreviousYears -] - -{ #category : #initialization } -MDLFlatDatePicker >> initialize [ - super initialize. - daysList := {'S' . 'M' . 'T' . 'W' . 'T' . 'F' . 'S'}. - calendar := MDLCalendar new. - onCompleteScript := '' -] - -{ #category : #testing } -MDLFlatDatePicker >> isInCurrentMonth: aDate [ - ^ aDate asMonth = self currentDate asMonth -] - -{ #category : #testing } -MDLFlatDatePicker >> isTodayAndNotSelected: aDate [ - ^ aDate = Date today and: [ aDate ~= self currentDate ] -] - -{ #category : #javascript } -MDLFlatDatePicker >> jsGoToMonth: aMonth on: html [ - ^ html jQuery ajax - callback: [ self goToMonth: aMonth ]; - onComplete: (self jsOnCompleteScriptOn: html) -] - -{ #category : #javascript } -MDLFlatDatePicker >> jsOnCompleteScript [ - ^ self onCompleteScript js -] - -{ #category : #javascript } -MDLFlatDatePicker >> jsOnCompleteScriptOn: html [ - ^ (html jQuery id: self id) load - html: [ :ajaxHtml | self renderCalendarOn: ajaxHtml ]; - onComplete: self jsOnCompleteScript -] - -{ #category : #javascript } -MDLFlatDatePicker >> jsUpdateDate: aDate on: html [ - ^ html jQuery ajax - callback: [ callback value: aDate. - self currentDate: aDate ]; - onComplete: (self jsOnCompleteScriptOn: html) -] - -{ #category : #accessing } -MDLFlatDatePicker >> onCompleteScript [ - ^ onCompleteScript -] - -{ #category : #accessing } -MDLFlatDatePicker >> onCompleteScript: anObject [ - onCompleteScript := anObject -] - -{ #category : #'private-rendering' } -MDLFlatDatePicker >> renderButtonNamed: aString renderingMethod: aSymbol on: html [ - html mdlButton - rippleEffect; - onClick: (((html jQuery id: self id) find: '.mdl-card__supporting-text') load html: [ :ajaxHtml | self perform: aSymbol with: ajaxHtml ]); - with: aString -] - -{ #category : #'private-rendering' } -MDLFlatDatePicker >> renderButtonWithIcon: anIcon action: aSymbol on: html [ - html - mdlCellDesktop: 2 - tablet: 1 - phone: 1 - with: [ html mdlButton - onClick: - (html jQuery ajax - callback: [ self perform: aSymbol ]; - onComplete: - ((html jQuery id: self id) load - html: [ :ajaxHtml | self renderCalendarOn: ajaxHtml ])); - rippleEffect; - style: 'color: rgba(0,0,0,0.7)'; - icon: anIcon ] -] - -{ #category : #rendering } -MDLFlatDatePicker >> renderCalendarBodyOn: html [ - html table - class: 'mdl-textfield--full-width'; - with: [ self renderDaysOn: html. - self renderWeeksOn: html ] -] - -{ #category : #rendering } -MDLFlatDatePicker >> renderCalendarContentOn: html [ - html mdlGrid - style: 'text-align: center; font-size: 14px; line-height:2; color: rgba(0,0,0,1)'; - with: [ - self renderCalendarHeaderOn: html. - html - mdlCellDesktop: 12 - tablet: 8 - phone: 4 - with: [ self renderCalendarBodyOn: html ] ] -] - -{ #category : #rendering } -MDLFlatDatePicker >> renderCalendarHeaderOn: html [ - self renderButtonWithIcon: 'navigate_before' action: #goToPreviousMonth on: html. - self renderCurrentMonthOn: html. - self renderButtonWithIcon: 'navigate_next' action: #goToNextMonth on: html -] - -{ #category : #rendering } -MDLFlatDatePicker >> renderCalendarOn: html [ - self renderCalendarTitleOn: html. - html div - class: 'mdl-card__supporting-text'; - with: [ self renderCalendarContentOn: html ] -] - -{ #category : #rendering } -MDLFlatDatePicker >> renderCalendarTitleOn: html [ - html div - mdlBackgroundColorPrimary; - class: 'mdl-calendar__title mdl-color-text--primary-contrast'; - with: [ html heading - level3; - with: self calendar printDateForHeader ] -] - -{ #category : #rendering } -MDLFlatDatePicker >> renderContentOn: html [ - self ensureId: html. - html div - id: self id; - class: self containerClass; - with: [ self renderCalendarOn: html ] -] - -{ #category : #rendering } -MDLFlatDatePicker >> renderCurrentMonthOn: html [ - html - mdlCellDesktop: 8 - tablet: 6 - phone: 2 - with: [ self - renderButtonNamed: self currentDate monthAbbreviation - renderingMethod: #renderMonthesOn: - on: html. - html space. - self - renderButtonNamed: self currentDate year greaseString - renderingMethod: #renderYearsOn: - on: html ] -] - -{ #category : #'private-rendering' } -MDLFlatDatePicker >> renderDate: aDate on: html [ - html tableData with: [ self displayDate: aDate on: html ] -] - -{ #category : #'private-rendering' } -MDLFlatDatePicker >> renderDaysOn: html [ - html tableColumnGroup: [ 1 to: 7 do: [ :i | html tableColumn width: '14,3%' ] ]. - html tableHead: [ html tableRow: [ self daysList do: [ :day | html tableHeading class: 'mdl-color-text--grey-600'; with: day ] ] ] -] - -{ #category : #'private-rendering' } -MDLFlatDatePicker >> renderMonthesOn: html [ - html mdlGrid - mdlTypographyTextCenter; - with: [ Date monthNames - do: [ :aString | - html mdlCell - class: 'month-cell'; - class: 'mdl-color-text--primary' if: aString = self currentDate monthName; - class: 'mdl-color-text--primary-contrast' if: aString = self currentDate monthName; - class: 'mdl-color--primary' if: aString = self currentDate monthName; - class: 'active' if: aString = self currentDate monthName; - onClick: (self jsGoToMonth: (Month indexOfMonth: aString) on: html); - desktopSize: 4; - with: aString ] ] -] - -{ #category : #'private-rendering' } -MDLFlatDatePicker >> renderWeeksOn: html [ - self currentDate asMonth weeks do: [ :aWeek | html tableRow: [ aWeek dates do: [ :aDate | self renderDate: aDate on: html ] ] ] -] - -{ #category : #'private-rendering' } -MDLFlatDatePicker >> renderYearsHeaderOn: html [ - self - renderYearsIntervalButtonWithIcon: 'navigate_before' - action: #goToPreviousYears - on: html. - html - mdlCellDesktop: 8 - tablet: 6 - phone: 2 - with: - (String - streamContents: [ :aStream | - aStream - nextPutAll: self calendar yearsInterval first greaseString; - nextPutAll: ' - '; - nextPutAll: self calendar yearsInterval last greaseString ]). - self - renderYearsIntervalButtonWithIcon: 'navigate_next' - action: #goToNextYears - on: html -] - -{ #category : #'private-rendering' } -MDLFlatDatePicker >> renderYearsIntervalButtonWithIcon: anIcon action: aSymbol on: html [ - html - mdlCellDesktop: 2 - tablet: 1 - phone: 1 - with: [ html mdlButton - onClick: (((html jQuery id: self id) find: '.mdl-card__supporting-text') load html: [ :ajaxHtml | self perform: aSymbol. self renderYearsOn: ajaxHtml ]); - rippleEffect; - style: 'color: rgba(0,0,0,0.7)'; - icon: anIcon ] -] - -{ #category : #'private-rendering' } -MDLFlatDatePicker >> renderYearsOn: html [ - html mdlGrid - mdlTypographyTextCenter; - with: [ self renderYearsHeaderOn: html. - self calendar yearsInterval - do: [ :aYear | - html mdlCell - class: 'year-cell'; - class: 'mdl-color-text--primary' if: aYear = self currentDate year; - class: 'mdl-color-text--primary-contrast' if: aYear = self currentDate year; - class: 'mdl-color--primary' if: aYear = self currentDate year; - class: 'active' if: aYear = self currentDate year; - onClick: - (html jQuery ajax - callback: [ self calendar goToYear: aYear ]; - onComplete: (self jsOnCompleteScriptOn: html)); - desktopSize: 4; - with: aYear greaseString ] ] -] - -{ #category : #testing } -MDLFlatDatePicker >> selectedDateIs: aDate [ - ^ aDate = self currentDate -] +" +I am a component displaying a calendar to let the user pick a date. +" +Class { + #name : #MDLFlatDatePicker, + #superclass : #MDLHighLevelWidget, + #instVars : [ + 'daysList', + 'calendar', + 'callback', + 'onCompleteScript' + ], + #category : #'Material-Design-Lite-Widgets-Calendar' +} + +{ #category : #accessing } +MDLFlatDatePicker >> calendar [ + ^ calendar +] + +{ #category : #accessing } +MDLFlatDatePicker >> calendar: anObject [ + calendar := anObject +] + +{ #category : #accessing } +MDLFlatDatePicker >> callback: aOneArgBlock [ + aOneArgBlock argumentCount ~= 1 + ifTrue: [ ^ self error: '1 argument expected' ]. + callback := aOneArgBlock +] + +{ #category : #accessing } +MDLFlatDatePicker >> containerClass [ + ^ 'mdl-calendar' +] + +{ #category : #accessing } +MDLFlatDatePicker >> currentDate [ + ^ self calendar currentDate +] + +{ #category : #accessing } +MDLFlatDatePicker >> currentDate: aDate [ + self calendar currentDate: aDate +] + +{ #category : #accessing } +MDLFlatDatePicker >> daysList [ + ^ daysList +] + +{ #category : #'private-rendering' } +MDLFlatDatePicker >> displayDate: aDate on: html [ + html mdlButton + class: 'mdl-color-text--primary' if: (self isTodayAndNotSelected: aDate); + class: 'mdl-color-text--primary-contrast mdl-color--primary' if: (self selectedDateIs: aDate); + class: 'disabled' if: (self isInCurrentMonth: aDate) not; + rippleEffect; + icon; + onClick: (self jsUpdateDate: aDate on: html); + with: aDate dayOfMonth greaseString +] + +{ #category : #private } +MDLFlatDatePicker >> goToMonth: anObject [ + calendar goToMonth: anObject +] + +{ #category : #private } +MDLFlatDatePicker >> goToNextMonth [ + self calendar selectNextMonth +] + +{ #category : #private } +MDLFlatDatePicker >> goToNextYears [ + self calendar selectNextYears +] + +{ #category : #private } +MDLFlatDatePicker >> goToPreviousMonth [ + self calendar selectPreviousMonth +] + +{ #category : #private } +MDLFlatDatePicker >> goToPreviousYears [ + self calendar selectPreviousYears +] + +{ #category : #initialization } +MDLFlatDatePicker >> initialize [ + super initialize. + daysList := {'S' . 'M' . 'T' . 'W' . 'T' . 'F' . 'S'}. + calendar := MDLCalendar new. + onCompleteScript := '' +] + +{ #category : #testing } +MDLFlatDatePicker >> isInCurrentMonth: aDate [ + ^ aDate asMonth = self currentDate asMonth +] + +{ #category : #testing } +MDLFlatDatePicker >> isTodayAndNotSelected: aDate [ + ^ aDate = Date today and: [ aDate ~= self currentDate ] +] + +{ #category : #javascript } +MDLFlatDatePicker >> jsGoToMonth: aMonth on: html [ + ^ html jQuery ajax + callback: [ self goToMonth: aMonth ]; + onComplete: (self jsOnCompleteScriptOn: html) +] + +{ #category : #javascript } +MDLFlatDatePicker >> jsOnCompleteScript [ + ^ self onCompleteScript js +] + +{ #category : #javascript } +MDLFlatDatePicker >> jsOnCompleteScriptOn: html [ + ^ (html jQuery id: self id) load + html: [ :ajaxHtml | self renderCalendarOn: ajaxHtml ]; + onComplete: self jsOnCompleteScript +] + +{ #category : #javascript } +MDLFlatDatePicker >> jsUpdateDate: aDate on: html [ + ^ html jQuery ajax + callback: [ callback value: aDate. + self currentDate: aDate ]; + onComplete: (self jsOnCompleteScriptOn: html) +] + +{ #category : #accessing } +MDLFlatDatePicker >> onCompleteScript [ + ^ onCompleteScript +] + +{ #category : #accessing } +MDLFlatDatePicker >> onCompleteScript: anObject [ + onCompleteScript := anObject +] + +{ #category : #'private-rendering' } +MDLFlatDatePicker >> renderButtonNamed: aString renderingMethod: aSymbol on: html [ + html mdlButton + rippleEffect; + onClick: (((html jQuery id: self id) find: '.mdl-card__supporting-text') load html: [ :ajaxHtml | self perform: aSymbol with: ajaxHtml ]); + with: aString +] + +{ #category : #'private-rendering' } +MDLFlatDatePicker >> renderButtonWithIcon: anIcon action: aSymbol on: html [ + html + mdlCellDesktop: 2 + tablet: 1 + phone: 1 + with: [ html mdlButton + onClick: + (html jQuery ajax + callback: [ self perform: aSymbol ]; + onComplete: + ((html jQuery id: self id) load + html: [ :ajaxHtml | self renderCalendarOn: ajaxHtml ])); + rippleEffect; + style: 'color: rgba(0,0,0,0.7)'; + icon: anIcon ] +] + +{ #category : #rendering } +MDLFlatDatePicker >> renderCalendarBodyOn: html [ + html table + class: 'mdl-textfield--full-width'; + with: [ self renderDaysOn: html. + self renderWeeksOn: html ] +] + +{ #category : #rendering } +MDLFlatDatePicker >> renderCalendarContentOn: html [ + html mdlGrid + style: 'text-align: center; font-size: 14px; line-height:2; color: rgba(0,0,0,1)'; + with: [ + self renderCalendarHeaderOn: html. + html + mdlCellDesktop: 12 + tablet: 8 + phone: 4 + with: [ self renderCalendarBodyOn: html ] ] +] + +{ #category : #rendering } +MDLFlatDatePicker >> renderCalendarHeaderOn: html [ + self renderButtonWithIcon: 'navigate_before' action: #goToPreviousMonth on: html. + self renderCurrentMonthOn: html. + self renderButtonWithIcon: 'navigate_next' action: #goToNextMonth on: html +] + +{ #category : #rendering } +MDLFlatDatePicker >> renderCalendarOn: html [ + self renderCalendarTitleOn: html. + html div + class: 'mdl-card__supporting-text'; + with: [ self renderCalendarContentOn: html ] +] + +{ #category : #rendering } +MDLFlatDatePicker >> renderCalendarTitleOn: html [ + html div + mdlBackgroundColorPrimary; + class: 'mdl-calendar__title mdl-color-text--primary-contrast'; + with: [ html heading + level3; + with: self calendar printDateForHeader ] +] + +{ #category : #rendering } +MDLFlatDatePicker >> renderContentOn: html [ + self ensureId: html. + html div + id: self id; + class: self containerClass; + with: [ self renderCalendarOn: html ] +] + +{ #category : #rendering } +MDLFlatDatePicker >> renderCurrentMonthOn: html [ + html + mdlCellDesktop: 8 + tablet: 6 + phone: 2 + with: [ self + renderButtonNamed: self currentDate monthAbbreviation + renderingMethod: #renderMonthesOn: + on: html. + html space. + self + renderButtonNamed: self currentDate year greaseString + renderingMethod: #renderYearsOn: + on: html ] +] + +{ #category : #'private-rendering' } +MDLFlatDatePicker >> renderDate: aDate on: html [ + html tableData with: [ self displayDate: aDate on: html ] +] + +{ #category : #'private-rendering' } +MDLFlatDatePicker >> renderDaysOn: html [ + html tableColumnGroup: [ 1 to: 7 do: [ :i | html tableColumn width: '14,3%' ] ]. + html tableHead: [ html tableRow: [ self daysList do: [ :day | html tableHeading class: 'mdl-color-text--grey-600'; with: day ] ] ] +] + +{ #category : #'private-rendering' } +MDLFlatDatePicker >> renderMonthesOn: html [ + html mdlGrid + mdlTypographyTextCenter; + with: [ Date monthNames + do: [ :aString | + html mdlCell + class: 'month-cell'; + class: 'mdl-color-text--primary' if: aString = self currentDate monthName; + class: 'mdl-color-text--primary-contrast' if: aString = self currentDate monthName; + class: 'mdl-color--primary' if: aString = self currentDate monthName; + class: 'active' if: aString = self currentDate monthName; + onClick: (self jsGoToMonth: (Month indexOfMonth: aString) on: html); + desktopSize: 4; + with: aString ] ] +] + +{ #category : #'private-rendering' } +MDLFlatDatePicker >> renderWeeksOn: html [ + self currentDate asMonth weeks do: [ :aWeek | html tableRow: [ aWeek dates do: [ :aDate | self renderDate: aDate on: html ] ] ] +] + +{ #category : #'private-rendering' } +MDLFlatDatePicker >> renderYearsHeaderOn: html [ + self + renderYearsIntervalButtonWithIcon: 'navigate_before' + action: #goToPreviousYears + on: html. + html + mdlCellDesktop: 8 + tablet: 6 + phone: 2 + with: + (String + streamContents: [ :aStream | + aStream + nextPutAll: self calendar yearsInterval first greaseString; + nextPutAll: ' - '; + nextPutAll: self calendar yearsInterval last greaseString ]). + self + renderYearsIntervalButtonWithIcon: 'navigate_next' + action: #goToNextYears + on: html +] + +{ #category : #'private-rendering' } +MDLFlatDatePicker >> renderYearsIntervalButtonWithIcon: anIcon action: aSymbol on: html [ + html + mdlCellDesktop: 2 + tablet: 1 + phone: 1 + with: [ html mdlButton + onClick: (((html jQuery id: self id) find: '.mdl-card__supporting-text') load html: [ :ajaxHtml | self perform: aSymbol. self renderYearsOn: ajaxHtml ]); + rippleEffect; + style: 'color: rgba(0,0,0,0.7)'; + icon: anIcon ] +] + +{ #category : #'private-rendering' } +MDLFlatDatePicker >> renderYearsOn: html [ + html mdlGrid + mdlTypographyTextCenter; + with: [ self renderYearsHeaderOn: html. + self calendar yearsInterval + do: [ :aYear | + html mdlCell + class: 'year-cell'; + class: 'mdl-color-text--primary' if: aYear = self currentDate year; + class: 'mdl-color-text--primary-contrast' if: aYear = self currentDate year; + class: 'mdl-color--primary' if: aYear = self currentDate year; + class: 'active' if: aYear = self currentDate year; + onClick: + (html jQuery ajax + callback: [ self calendar goToYear: aYear ]; + onComplete: (self jsOnCompleteScriptOn: html)); + desktopSize: 4; + with: aYear greaseString ] ] +] + +{ #category : #testing } +MDLFlatDatePicker >> selectedDateIs: aDate [ + ^ aDate = self currentDate +] diff --git a/src/Material-Design-Lite-Widgets/MDLFooter.class.st b/src/Material-Design-Lite-Widgets/MDLFooter.class.st index 59803538..0eaa1775 100644 --- a/src/Material-Design-Lite-Widgets/MDLFooter.class.st +++ b/src/Material-Design-Lite-Widgets/MDLFooter.class.st @@ -1,82 +1,82 @@ -" -I am a MDLFooter. -I'm divided in 3 rows : topSection middleSection bottomSection. - -Each section needs a collection of links to work, and a title. - -The links in the middle section will be displayed vertically , whereas the top and bottom sections will be displayed horizontally. (it's a choice, you can implement your own footer if you want to do it in an other way). - -The middle section can contain multiple Dropdown sections. - -Top and Bottom sections can receive only one section (it is still a choice). -" -Class { - #name : #MDLFooter, - #superclass : #MDLWidget, - #instVars : [ - 'topLeftSection', - 'topRightSection', - 'middleSection', - 'bottomSection' - ], - #category : #'Material-Design-Lite-Widgets-Footer' -} - -{ #category : #'public api' } -MDLFooter >> atBottomAddLinks: links [ - "Links must be formatted as following : (header -> #((label1->url1) . (label2 -> url2)))" - - bottomSection isNilSection - ifTrue: [ bottomSection := MDLFooterLinksSection new ]. - bottomSection := bottomSection - addLinksList: - (MDLMegaFooterLinksList new - addLinks: links; - yourself) -] - -{ #category : #'public api' } -MDLFooter >> atMiddleAddLinks: links [ - "Links must be formatted as following : #(header -> #( (label1->url1) . (label2 -> url2)))" - - | list | - middleSection isNilSection - ifTrue: [ middleSection := MDLFooterDropdownSection new ]. - list := links collect: [ :anAssociation | MDLMegaFooterLinksList new addLinks: anAssociation ]. - middleSection addLinksLists: list -] - -{ #category : #'public api' } -MDLFooter >> atTopLeftAddComponents: components [ - "Components must be an array of WAComponents (render: will be called on them)" - topLeftSection isNilSection - ifTrue: [ topLeftSection := MDLFooterComponentsSection new ]. - topLeftSection := topLeftSection addComponents: components -] - -{ #category : #'public api' } -MDLFooter >> atTopRightAddComponents: components [ - "Components must be an array of WAComponents (render: will be called on them)" - topRightSection isNilSection - ifTrue: [ topRightSection := MDLFooterComponentsSection new ]. - topRightSection := topRightSection addComponents: components -] - -{ #category : #initialization } -MDLFooter >> initialize [ - super initialize. - topLeftSection := MDLFooterNilSection new. - topRightSection := MDLFooterNilSection new. - middleSection := MDLFooterNilSection new. - bottomSection := MDLFooterNilSection new -] - -{ #category : #rendering } -MDLFooter >> renderContentOn: html [ - html mdlFooter: [ - html mdlFooterTopSection: [ - html mdlFooterLeftSection: [ topLeftSection renderSectionOn: html ]. - html mdlFooterRightSection: [ topRightSection renderSectionOn: html ] ]. - html mdlFooterMiddleSection: [ middleSection renderSectionOn: html ]. - html mdlFooterBottomSection: [ bottomSection renderSectionOn: html ] ] -] +" +I am a MDLFooter. +I'm divided in 3 rows : topSection middleSection bottomSection. + +Each section needs a collection of links to work, and a title. + +The links in the middle section will be displayed vertically , whereas the top and bottom sections will be displayed horizontally. (it's a choice, you can implement your own footer if you want to do it in an other way). + +The middle section can contain multiple Dropdown sections. + +Top and Bottom sections can receive only one section (it is still a choice). +" +Class { + #name : #MDLFooter, + #superclass : #MDLWidget, + #instVars : [ + 'topLeftSection', + 'topRightSection', + 'middleSection', + 'bottomSection' + ], + #category : #'Material-Design-Lite-Widgets-Footer' +} + +{ #category : #'public api' } +MDLFooter >> atBottomAddLinks: links [ + "Links must be formatted as following : (header -> #((label1->url1) . (label2 -> url2)))" + + bottomSection isNilSection + ifTrue: [ bottomSection := MDLFooterLinksSection new ]. + bottomSection := bottomSection + addLinksList: + (MDLMegaFooterLinksList new + addLinks: links; + yourself) +] + +{ #category : #'public api' } +MDLFooter >> atMiddleAddLinks: links [ + "Links must be formatted as following : #(header -> #( (label1->url1) . (label2 -> url2)))" + + | list | + middleSection isNilSection + ifTrue: [ middleSection := MDLFooterDropdownSection new ]. + list := links collect: [ :anAssociation | MDLMegaFooterLinksList new addLinks: anAssociation ]. + middleSection addLinksLists: list +] + +{ #category : #'public api' } +MDLFooter >> atTopLeftAddComponents: components [ + "Components must be an array of WAComponents (render: will be called on them)" + topLeftSection isNilSection + ifTrue: [ topLeftSection := MDLFooterComponentsSection new ]. + topLeftSection := topLeftSection addComponents: components +] + +{ #category : #'public api' } +MDLFooter >> atTopRightAddComponents: components [ + "Components must be an array of WAComponents (render: will be called on them)" + topRightSection isNilSection + ifTrue: [ topRightSection := MDLFooterComponentsSection new ]. + topRightSection := topRightSection addComponents: components +] + +{ #category : #initialization } +MDLFooter >> initialize [ + super initialize. + topLeftSection := MDLFooterNilSection new. + topRightSection := MDLFooterNilSection new. + middleSection := MDLFooterNilSection new. + bottomSection := MDLFooterNilSection new +] + +{ #category : #rendering } +MDLFooter >> renderContentOn: html [ + html mdlFooter: [ + html mdlFooterTopSection: [ + html mdlFooterLeftSection: [ topLeftSection renderSectionOn: html ]. + html mdlFooterRightSection: [ topRightSection renderSectionOn: html ] ]. + html mdlFooterMiddleSection: [ middleSection renderSectionOn: html ]. + html mdlFooterBottomSection: [ bottomSection renderSectionOn: html ] ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLFooterAbstractSection.class.st b/src/Material-Design-Lite-Widgets/MDLFooterAbstractSection.class.st index 78d97682..59bb096a 100644 --- a/src/Material-Design-Lite-Widgets/MDLFooterAbstractSection.class.st +++ b/src/Material-Design-Lite-Widgets/MDLFooterAbstractSection.class.st @@ -1,15 +1,15 @@ -Class { - #name : #MDLFooterAbstractSection, - #superclass : #Object, - #category : 'Material-Design-Lite-Widgets-Footer' -} - -{ #category : #testing } -MDLFooterAbstractSection >> isNilSection [ - ^ false -] - -{ #category : #rendering } -MDLFooterAbstractSection >> renderSectionOn: html [ - self subclassResponsibility -] +Class { + #name : #MDLFooterAbstractSection, + #superclass : #Object, + #category : 'Material-Design-Lite-Widgets-Footer' +} + +{ #category : #testing } +MDLFooterAbstractSection >> isNilSection [ + ^ false +] + +{ #category : #rendering } +MDLFooterAbstractSection >> renderSectionOn: html [ + self subclassResponsibility +] diff --git a/src/Material-Design-Lite-Widgets/MDLFooterComponentsSection.class.st b/src/Material-Design-Lite-Widgets/MDLFooterComponentsSection.class.st index 2a6fc602..4fb82041 100644 --- a/src/Material-Design-Lite-Widgets/MDLFooterComponentsSection.class.st +++ b/src/Material-Design-Lite-Widgets/MDLFooterComponentsSection.class.st @@ -1,18 +1,18 @@ -Class { - #name : #MDLFooterComponentsSection, - #superclass : #MDLFooterAbstractSection, - #instVars : [ - 'components' - ], - #category : 'Material-Design-Lite-Widgets-Footer' -} - -{ #category : #adding } -MDLFooterComponentsSection >> addComponents: aComponentsCollection [ - components := aComponentsCollection -] - -{ #category : #rendering } -MDLFooterComponentsSection >> renderSectionOn: html [ - components do: [ :aComponent | html render: aComponent ] -] +Class { + #name : #MDLFooterComponentsSection, + #superclass : #MDLFooterAbstractSection, + #instVars : [ + 'components' + ], + #category : 'Material-Design-Lite-Widgets-Footer' +} + +{ #category : #adding } +MDLFooterComponentsSection >> addComponents: aComponentsCollection [ + components := aComponentsCollection +] + +{ #category : #rendering } +MDLFooterComponentsSection >> renderSectionOn: html [ + components do: [ :aComponent | html render: aComponent ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLFooterDropdownSection.class.st b/src/Material-Design-Lite-Widgets/MDLFooterDropdownSection.class.st index a3292b76..371cfc0c 100644 --- a/src/Material-Design-Lite-Widgets/MDLFooterDropdownSection.class.st +++ b/src/Material-Design-Lite-Widgets/MDLFooterDropdownSection.class.st @@ -1,24 +1,24 @@ -Class { - #name : #MDLFooterDropdownSection, - #superclass : #MDLFooterAbstractSection, - #instVars : [ - 'linksLists' - ], - #category : 'Material-Design-Lite-Widgets-Footer' -} - -{ #category : #adding } -MDLFooterDropdownSection >> addLinksLists: lists [ - linksLists addAll: lists -] - -{ #category : #initialization } -MDLFooterDropdownSection >> initialize [ - super initialize. - linksLists := OrderedCollection new -] - -{ #category : #rendering } -MDLFooterDropdownSection >> renderSectionOn: html [ - linksLists do: [ :aList | html mdlFooterDropdownSection: [ aList renderLinksWithHeaderOn: html ] ]. -] +Class { + #name : #MDLFooterDropdownSection, + #superclass : #MDLFooterAbstractSection, + #instVars : [ + 'linksLists' + ], + #category : 'Material-Design-Lite-Widgets-Footer' +} + +{ #category : #adding } +MDLFooterDropdownSection >> addLinksLists: lists [ + linksLists addAll: lists +] + +{ #category : #initialization } +MDLFooterDropdownSection >> initialize [ + super initialize. + linksLists := OrderedCollection new +] + +{ #category : #rendering } +MDLFooterDropdownSection >> renderSectionOn: html [ + linksLists do: [ :aList | html mdlFooterDropdownSection: [ aList renderLinksWithHeaderOn: html ] ]. +] diff --git a/src/Material-Design-Lite-Widgets/MDLFooterLinksSection.class.st b/src/Material-Design-Lite-Widgets/MDLFooterLinksSection.class.st index 955b2d4b..985b4749 100644 --- a/src/Material-Design-Lite-Widgets/MDLFooterLinksSection.class.st +++ b/src/Material-Design-Lite-Widgets/MDLFooterLinksSection.class.st @@ -1,24 +1,24 @@ -Class { - #name : #MDLFooterLinksSection, - #superclass : #MDLFooterAbstractSection, - #instVars : [ - 'linksList' - ], - #category : 'Material-Design-Lite-Widgets-Footer' -} - -{ #category : #adding } -MDLFooterLinksSection >> addLinksList: aLinksList [ - linksList := aLinksList -] - -{ #category : #initialization } -MDLFooterLinksSection >> initialize [ - super initialize. - linksList := MDLMegaFooterLinksList new -] - -{ #category : #rendering } -MDLFooterLinksSection >> renderSectionOn: html [ - linksList renderLinksWithLogoOn: html -] +Class { + #name : #MDLFooterLinksSection, + #superclass : #MDLFooterAbstractSection, + #instVars : [ + 'linksList' + ], + #category : 'Material-Design-Lite-Widgets-Footer' +} + +{ #category : #adding } +MDLFooterLinksSection >> addLinksList: aLinksList [ + linksList := aLinksList +] + +{ #category : #initialization } +MDLFooterLinksSection >> initialize [ + super initialize. + linksList := MDLMegaFooterLinksList new +] + +{ #category : #rendering } +MDLFooterLinksSection >> renderSectionOn: html [ + linksList renderLinksWithLogoOn: html +] diff --git a/src/Material-Design-Lite-Widgets/MDLFooterNilSection.class.st b/src/Material-Design-Lite-Widgets/MDLFooterNilSection.class.st index 3cea7a8b..da6a3270 100644 --- a/src/Material-Design-Lite-Widgets/MDLFooterNilSection.class.st +++ b/src/Material-Design-Lite-Widgets/MDLFooterNilSection.class.st @@ -1,20 +1,20 @@ -Class { - #name : #MDLFooterNilSection, - #superclass : #MDLFooterAbstractSection, - #category : 'Material-Design-Lite-Widgets-Footer' -} - -{ #category : #adding } -MDLFooterNilSection >> addLinks: someLinks [ - self shouldNotImplement -] - -{ #category : #testing } -MDLFooterNilSection >> isNilSection [ - ^ true -] - -{ #category : #testing } -MDLFooterNilSection >> renderSectionOn: html [ - "do nothing" -] +Class { + #name : #MDLFooterNilSection, + #superclass : #MDLFooterAbstractSection, + #category : 'Material-Design-Lite-Widgets-Footer' +} + +{ #category : #adding } +MDLFooterNilSection >> addLinks: someLinks [ + self shouldNotImplement +] + +{ #category : #testing } +MDLFooterNilSection >> isNilSection [ + ^ true +] + +{ #category : #testing } +MDLFooterNilSection >> renderSectionOn: html [ + "do nothing" +] diff --git a/src/Material-Design-Lite-Widgets/MDLHideExpansionStrategy.class.st b/src/Material-Design-Lite-Widgets/MDLHideExpansionStrategy.class.st index 9bb772df..76760f5c 100644 --- a/src/Material-Design-Lite-Widgets/MDLHideExpansionStrategy.class.st +++ b/src/Material-Design-Lite-Widgets/MDLHideExpansionStrategy.class.st @@ -1,22 +1,22 @@ -" -I am an expansion strategy that uses CSS properties to hide the expansion panel content when it should not be shown. - -I also use a little of javascript to update the icon according to the state of the panel. -" -Class { - #name : #MDLHideExpansionStrategy, - #superclass : #MDLExpansionStrategy, - #category : #'Material-Design-Lite-Widgets-Expansion' -} - -{ #category : #javascript } -MDLHideExpansionStrategy >> customize: anExpansionPanelHeader in: anExpansionPanel on: html [ - "Do nothing here." - - -] - -{ #category : #rendering } -MDLHideExpansionStrategy >> renderExpansionPanel: anExpansionPanel contentOn: html [ - anExpansionPanel expandedBlock value: html -] +" +I am an expansion strategy that uses CSS properties to hide the expansion panel content when it should not be shown. + +I also use a little of javascript to update the icon according to the state of the panel. +" +Class { + #name : #MDLHideExpansionStrategy, + #superclass : #MDLExpansionStrategy, + #category : #'Material-Design-Lite-Widgets-Expansion' +} + +{ #category : #javascript } +MDLHideExpansionStrategy >> customize: anExpansionPanelHeader in: anExpansionPanel on: html [ + "Do nothing here." + + +] + +{ #category : #rendering } +MDLHideExpansionStrategy >> renderExpansionPanel: anExpansionPanel contentOn: html [ + anExpansionPanel expandedBlock value: html +] diff --git a/src/Material-Design-Lite-Widgets/MDLHighLevelWidget.class.st b/src/Material-Design-Lite-Widgets/MDLHighLevelWidget.class.st index a16b1a92..a08067c1 100644 --- a/src/Material-Design-Lite-Widgets/MDLHighLevelWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLHighLevelWidget.class.st @@ -1,114 +1,114 @@ -" -I represent an abstract class for high level widgets. - -Interesting point is that I have properties through a Dictionary which allow me to add some behaviours. My properties should have a selector as key and an array of parameters as value. -" -Class { - #name : #MDLHighLevelWidget, - #superclass : #MDLWidget, - #instVars : [ - 'properties' - ], - #category : #'Material-Design-Lite-Widgets' -} - -{ #category : #accessing } -MDLHighLevelWidget >> addProperties: aDictionary [ - properties addAll: aDictionary -] - -{ #category : #actions } -MDLHighLevelWidget >> addPropertiesToBrush: aBrush [ - self properties keysAndValuesDo: [ :aSymbol :arguments | aBrush perform: aSymbol withArguments: arguments ] -] - -{ #category : #accessing } -MDLHighLevelWidget >> class: aString [ - | stringToAdd | - aString isEmptyOrNil ifTrue: [ ^ self ]. - - stringToAdd := self - propertiesAt: #class: - ifPresent: [ :oldClasses | - stringToAdd := String - streamContents: [ :aStream | - aStream - nextPutAll: oldClasses anyOne; - space; - nextPutAll: aString ] ] - ifAbsent: [ aString ]. - - self propertiesAt: #class: put: (Array with: stringToAdd) -] - -{ #category : #accessing } -MDLHighLevelWidget >> htmlClass [ - "htmlClass because it can cause problems to have a #class method in objects." - - ^ self propertiesAt: #class ifPresent: [ :array | array anyOne ] ifAbsent: [ nil ] -] - -{ #category : #accessing } -MDLHighLevelWidget >> id [ - ^ self propertiesAt: #id: ifPresent: [ :array | array anyOne ] ifAbsent: [ nil ] -] - -{ #category : #accessing } -MDLHighLevelWidget >> id: aString [ - self propertiesAt: #id: put: (Array with: aString) -] - -{ #category : #initialization } -MDLHighLevelWidget >> initialize [ - super initialize. - properties := OrderedDictionary new -] - -{ #category : #accessing } -MDLHighLevelWidget >> onClick: anObject [ - self propertiesAt: #onClick: put: (Array with: anObject) -] - -{ #category : #accessing } -MDLHighLevelWidget >> properties [ - ^ properties -] - -{ #category : #accessing } -MDLHighLevelWidget >> propertiesAt: aString [ - ^ self properties at: aString -] - -{ #category : #accessing } -MDLHighLevelWidget >> propertiesAt: aString ifAbsent: aBlock [ - ^ self properties at: aString ifAbsent: aBlock -] - -{ #category : #accessing } -MDLHighLevelWidget >> propertiesAt: aString ifPresent: aBlock ifAbsent: anotherBlock [ - ^ self properties at: aString ifPresent: aBlock ifAbsent: anotherBlock -] - -{ #category : #accessing } -MDLHighLevelWidget >> propertiesAt: aString put: anArray [ - self properties at: aString put: anArray -] - -{ #category : #accessing } -MDLHighLevelWidget >> style: aString [ - | stringToAdd | - aString isEmptyOrNil ifTrue: [ ^ self ]. - - stringToAdd := self - propertiesAt: #style: - ifPresent: [ :oldStyle | - String - streamContents: [ :aStream | - aStream - nextPutAll: oldStyle anyOne; - space; - nextPutAll: aString ] ] - ifAbsent: [ aString ]. - - self propertiesAt: #style: put: {stringToAdd} -] +" +I represent an abstract class for high level widgets. + +Interesting point is that I have properties through a Dictionary which allow me to add some behaviours. My properties should have a selector as key and an array of parameters as value. +" +Class { + #name : #MDLHighLevelWidget, + #superclass : #MDLWidget, + #instVars : [ + 'properties' + ], + #category : #'Material-Design-Lite-Widgets' +} + +{ #category : #accessing } +MDLHighLevelWidget >> addProperties: aDictionary [ + properties addAll: aDictionary +] + +{ #category : #actions } +MDLHighLevelWidget >> addPropertiesToBrush: aBrush [ + self properties keysAndValuesDo: [ :aSymbol :arguments | aBrush perform: aSymbol withArguments: arguments ] +] + +{ #category : #accessing } +MDLHighLevelWidget >> class: aString [ + | stringToAdd | + aString isEmptyOrNil ifTrue: [ ^ self ]. + + stringToAdd := self + propertiesAt: #class: + ifPresent: [ :oldClasses | + stringToAdd := String + streamContents: [ :aStream | + aStream + nextPutAll: oldClasses anyOne; + space; + nextPutAll: aString ] ] + ifAbsent: [ aString ]. + + self propertiesAt: #class: put: (Array with: stringToAdd) +] + +{ #category : #accessing } +MDLHighLevelWidget >> htmlClass [ + "htmlClass because it can cause problems to have a #class method in objects." + + ^ self propertiesAt: #class ifPresent: [ :array | array anyOne ] ifAbsent: [ nil ] +] + +{ #category : #accessing } +MDLHighLevelWidget >> id [ + ^ self propertiesAt: #id: ifPresent: [ :array | array anyOne ] ifAbsent: [ nil ] +] + +{ #category : #accessing } +MDLHighLevelWidget >> id: aString [ + self propertiesAt: #id: put: (Array with: aString) +] + +{ #category : #initialization } +MDLHighLevelWidget >> initialize [ + super initialize. + properties := OrderedDictionary new +] + +{ #category : #accessing } +MDLHighLevelWidget >> onClick: anObject [ + self propertiesAt: #onClick: put: (Array with: anObject) +] + +{ #category : #accessing } +MDLHighLevelWidget >> properties [ + ^ properties +] + +{ #category : #accessing } +MDLHighLevelWidget >> propertiesAt: aString [ + ^ self properties at: aString +] + +{ #category : #accessing } +MDLHighLevelWidget >> propertiesAt: aString ifAbsent: aBlock [ + ^ self properties at: aString ifAbsent: aBlock +] + +{ #category : #accessing } +MDLHighLevelWidget >> propertiesAt: aString ifPresent: aBlock ifAbsent: anotherBlock [ + ^ self properties at: aString ifPresent: aBlock ifAbsent: anotherBlock +] + +{ #category : #accessing } +MDLHighLevelWidget >> propertiesAt: aString put: anArray [ + self properties at: aString put: anArray +] + +{ #category : #accessing } +MDLHighLevelWidget >> style: aString [ + | stringToAdd | + aString isEmptyOrNil ifTrue: [ ^ self ]. + + stringToAdd := self + propertiesAt: #style: + ifPresent: [ :oldStyle | + String + streamContents: [ :aStream | + aStream + nextPutAll: oldStyle anyOne; + space; + nextPutAll: aString ] ] + ifAbsent: [ aString ]. + + self propertiesAt: #style: put: {stringToAdd} +] diff --git a/src/Material-Design-Lite-Widgets/MDLIconComponent.class.st b/src/Material-Design-Lite-Widgets/MDLIconComponent.class.st index a45ac400..6757f8ff 100644 --- a/src/Material-Design-Lite-Widgets/MDLIconComponent.class.st +++ b/src/Material-Design-Lite-Widgets/MDLIconComponent.class.st @@ -1,29 +1,29 @@ -" -Description --------------------- - -I am a brush to create a -" -Class { - #name : #MDLIconComponent, - #superclass : #WAComponent, - #instVars : [ - 'iconName' - ], - #category : #'Material-Design-Lite-Widgets' -} - -{ #category : #accessing } -MDLIconComponent >> iconName [ - ^ iconName -] - -{ #category : #accessing } -MDLIconComponent >> iconName: anObject [ - iconName := anObject -] - -{ #category : #rendering } -MDLIconComponent >> renderContentOn: html [ - iconName ifNotNil: [ html mdlIcon: iconName ] ifNil: [ html text: 'No icon name set' ] -] +" +Description +-------------------- + +I am a brush to create a +" +Class { + #name : #MDLIconComponent, + #superclass : #WAComponent, + #instVars : [ + 'iconName' + ], + #category : #'Material-Design-Lite-Widgets' +} + +{ #category : #accessing } +MDLIconComponent >> iconName [ + ^ iconName +] + +{ #category : #accessing } +MDLIconComponent >> iconName: anObject [ + iconName := anObject +] + +{ #category : #rendering } +MDLIconComponent >> renderContentOn: html [ + iconName ifNotNil: [ html mdlIcon: iconName ] ifNil: [ html text: 'No icon name set' ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLIconDrawerSection.class.st b/src/Material-Design-Lite-Widgets/MDLIconDrawerSection.class.st index b0eee6be..44bccfcc 100644 --- a/src/Material-Design-Lite-Widgets/MDLIconDrawerSection.class.st +++ b/src/Material-Design-Lite-Widgets/MDLIconDrawerSection.class.st @@ -1,26 +1,26 @@ -Class { - #name : #MDLIconDrawerSection, - #superclass : #MDLLinkingLayoutSection, - #category : 'Material-Design-Lite-Widgets-Header' -} - -{ #category : #accessing } -MDLIconDrawerSection >> links: someLinks [ - "here links must be seaside components" - ^ super links: someLinks -] - -{ #category : #'as yet unclassified' } -MDLIconDrawerSection >> renderContentOn: html [ - html - mdlLayoutDrawer: [ - html mdlLayoutTitle - style: 'border-bottom: 1px solid #e0e0e0; margin: 0px 0px 16px 0px'; - with: layout title. - self renderLinksOn: html ] -] - -{ #category : #'as yet unclassified' } -MDLIconDrawerSection >> renderLinksOn: html [ - links do: [ :aLink | html render: aLink ] -] +Class { + #name : #MDLIconDrawerSection, + #superclass : #MDLLinkingLayoutSection, + #category : 'Material-Design-Lite-Widgets-Header' +} + +{ #category : #accessing } +MDLIconDrawerSection >> links: someLinks [ + "here links must be seaside components" + ^ super links: someLinks +] + +{ #category : #'as yet unclassified' } +MDLIconDrawerSection >> renderContentOn: html [ + html + mdlLayoutDrawer: [ + html mdlLayoutTitle + style: 'border-bottom: 1px solid #e0e0e0; margin: 0px 0px 16px 0px'; + with: layout title. + self renderLinksOn: html ] +] + +{ #category : #'as yet unclassified' } +MDLIconDrawerSection >> renderLinksOn: html [ + links do: [ :aLink | html render: aLink ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLInsensitiveBeginsWithFilter.class.st b/src/Material-Design-Lite-Widgets/MDLInsensitiveBeginsWithFilter.class.st index 4721f978..4f53a52b 100644 --- a/src/Material-Design-Lite-Widgets/MDLInsensitiveBeginsWithFilter.class.st +++ b/src/Material-Design-Lite-Widgets/MDLInsensitiveBeginsWithFilter.class.st @@ -1,13 +1,13 @@ -" -I am a nested list filter keeping only elements whose name begins with the pattern passed by the user in an insensitive way. -" -Class { - #name : #MDLInsensitiveBeginsWithFilter, - #superclass : #MDLAbstractFilter, - #category : 'Material-Design-Lite-Widgets-List' -} - -{ #category : #accessing } -MDLInsensitiveBeginsWithFilter class >> formatedElement: aString matches: aPattern [ - ^ aString asLowercase beginsWith: aPattern asLowercase -] +" +I am a nested list filter keeping only elements whose name begins with the pattern passed by the user in an insensitive way. +" +Class { + #name : #MDLInsensitiveBeginsWithFilter, + #superclass : #MDLAbstractFilter, + #category : 'Material-Design-Lite-Widgets-List' +} + +{ #category : #accessing } +MDLInsensitiveBeginsWithFilter class >> formatedElement: aString matches: aPattern [ + ^ aString asLowercase beginsWith: aPattern asLowercase +] diff --git a/src/Material-Design-Lite-Widgets/MDLInsensitiveSubstringFilter.class.st b/src/Material-Design-Lite-Widgets/MDLInsensitiveSubstringFilter.class.st index 1f2ed870..e6a50dff 100644 --- a/src/Material-Design-Lite-Widgets/MDLInsensitiveSubstringFilter.class.st +++ b/src/Material-Design-Lite-Widgets/MDLInsensitiveSubstringFilter.class.st @@ -1,13 +1,13 @@ -" -I am a nested list filter keeping only elements whose name includes the pattern passed by the user, non case sensitive. -" -Class { - #name : #MDLInsensitiveSubstringFilter, - #superclass : #MDLAbstractFilter, - #category : 'Material-Design-Lite-Widgets-List' -} - -{ #category : #accessing } -MDLInsensitiveSubstringFilter class >> formatedElement: aString matches: aPattern [ - ^ aString asLowercase includesSubstring: aPattern asLowercase -] +" +I am a nested list filter keeping only elements whose name includes the pattern passed by the user, non case sensitive. +" +Class { + #name : #MDLInsensitiveSubstringFilter, + #superclass : #MDLAbstractFilter, + #category : 'Material-Design-Lite-Widgets-List' +} + +{ #category : #accessing } +MDLInsensitiveSubstringFilter class >> formatedElement: aString matches: aPattern [ + ^ aString asLowercase includesSubstring: aPattern asLowercase +] diff --git a/src/Material-Design-Lite-Widgets/MDLLayoutWidget.class.st b/src/Material-Design-Lite-Widgets/MDLLayoutWidget.class.st index 923d5710..b8c58fac 100644 --- a/src/Material-Design-Lite-Widgets/MDLLayoutWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLLayoutWidget.class.st @@ -1,110 +1,110 @@ -Class { - #name : #MDLLayoutWidget, - #superclass : #MDLWidget, - #instVars : [ - 'title', - 'icon', - 'headerSection', - 'drawerSection', - 'contentBlock', - 'brush' - ], - #category : 'Material-Design-Lite-Widgets-Header' -} - -{ #category : #accessing } -MDLLayoutWidget >> contentBlock [ - ^ contentBlock -] - -{ #category : #accessing } -MDLLayoutWidget >> contentBlock: anObject [ - contentBlock := anObject -] - -{ #category : #accessing } -MDLLayoutWidget >> drawerSection [ - ^ drawerSection -] - -{ #category : #accessing } -MDLLayoutWidget >> drawerSection: anObject [ - anObject layout: self. - drawerSection := anObject -] - -{ #category : #options } -MDLLayoutWidget >> fixedDrawer [ - ^ brush fixedDrawer -] - -{ #category : #options } -MDLLayoutWidget >> fixedHeader [ - ^ brush fixedHeader -] - -{ #category : #options } -MDLLayoutWidget >> fixedTabs [ - ^ brush fixedTabs -] - -{ #category : #accessing } -MDLLayoutWidget >> headerSection [ - ^ headerSection -] - -{ #category : #accessing } -MDLLayoutWidget >> headerSection: anObject [ - anObject layout: self. - headerSection := anObject -] - -{ #category : #accessing } -MDLLayoutWidget >> icon [ - ^ icon -] - -{ #category : #accessing } -MDLLayoutWidget >> icon: anObject [ - icon := anObject -] - -{ #category : #initialization } -MDLLayoutWidget >> initialize [ - super initialize. - title := 'Define a title'. - icon := MDLIconComponent new. - headerSection := MDLNilLayoutSection new. - drawerSection := MDLNilLayoutSection new. - contentBlock := [ ]. - brush := MDLLayout new. -] - -{ #category : #options } -MDLLayoutWidget >> noDesktopDrawerButton [ - ^ brush noDesktopDrawerButton -] - -{ #category : #options } -MDLLayoutWidget >> noDrawerButton [ - ^ brush noDrawerButton -] - -{ #category : #rendering } -MDLLayoutWidget >> renderContentOn: html [ - (html brush: brush) - with: [ - html render: headerSection. - html render: drawerSection. - html mdlLayoutContent: contentBlock ]. -] - -{ #category : #accessing } -MDLLayoutWidget >> title [ - ^ title -] - -{ #category : #accessing } -MDLLayoutWidget >> title: anObject [ - title := anObject -] +Class { + #name : #MDLLayoutWidget, + #superclass : #MDLWidget, + #instVars : [ + 'title', + 'icon', + 'headerSection', + 'drawerSection', + 'contentBlock', + 'brush' + ], + #category : 'Material-Design-Lite-Widgets-Header' +} + +{ #category : #accessing } +MDLLayoutWidget >> contentBlock [ + ^ contentBlock +] + +{ #category : #accessing } +MDLLayoutWidget >> contentBlock: anObject [ + contentBlock := anObject +] + +{ #category : #accessing } +MDLLayoutWidget >> drawerSection [ + ^ drawerSection +] + +{ #category : #accessing } +MDLLayoutWidget >> drawerSection: anObject [ + anObject layout: self. + drawerSection := anObject +] + +{ #category : #options } +MDLLayoutWidget >> fixedDrawer [ + ^ brush fixedDrawer +] + +{ #category : #options } +MDLLayoutWidget >> fixedHeader [ + ^ brush fixedHeader +] + +{ #category : #options } +MDLLayoutWidget >> fixedTabs [ + ^ brush fixedTabs +] + +{ #category : #accessing } +MDLLayoutWidget >> headerSection [ + ^ headerSection +] + +{ #category : #accessing } +MDLLayoutWidget >> headerSection: anObject [ + anObject layout: self. + headerSection := anObject +] + +{ #category : #accessing } +MDLLayoutWidget >> icon [ + ^ icon +] + +{ #category : #accessing } +MDLLayoutWidget >> icon: anObject [ + icon := anObject +] + +{ #category : #initialization } +MDLLayoutWidget >> initialize [ + super initialize. + title := 'Define a title'. + icon := MDLIconComponent new. + headerSection := MDLNilLayoutSection new. + drawerSection := MDLNilLayoutSection new. + contentBlock := [ ]. + brush := MDLLayout new. +] + +{ #category : #options } +MDLLayoutWidget >> noDesktopDrawerButton [ + ^ brush noDesktopDrawerButton +] + +{ #category : #options } +MDLLayoutWidget >> noDrawerButton [ + ^ brush noDrawerButton +] + +{ #category : #rendering } +MDLLayoutWidget >> renderContentOn: html [ + (html brush: brush) + with: [ + html render: headerSection. + html render: drawerSection. + html mdlLayoutContent: contentBlock ]. +] + +{ #category : #accessing } +MDLLayoutWidget >> title [ + ^ title +] + +{ #category : #accessing } +MDLLayoutWidget >> title: anObject [ + title := anObject +] diff --git a/src/Material-Design-Lite-Widgets/MDLLazyExpansionStrategy.class.st b/src/Material-Design-Lite-Widgets/MDLLazyExpansionStrategy.class.st index 514d3c7a..56432b87 100644 --- a/src/Material-Design-Lite-Widgets/MDLLazyExpansionStrategy.class.st +++ b/src/Material-Design-Lite-Widgets/MDLLazyExpansionStrategy.class.st @@ -1,42 +1,42 @@ -" -I am a lazy expansion strategy. -I combine the best from MDLHideExpansionStrategy and MDLAjaxExpansionStrategy to load the panel content only once when it is needed. - -That is to say, if the panel is initially rendered folded, the first time the user click the expansion panel to expand it, I will perform an AJAX call to ask the server to render the content. -Then, next times the user click on the expansion panel, I will behave as MDLHideExpansionStrategy. - -If the panel is initially rendered expanded, I behave exactly as MDLHideExpansionStrategy. -" -Class { - #name : #MDLLazyExpansionStrategy, - #superclass : #MDLExpansionStrategy, - #instVars : [ - 'currentStrategy' - ], - #category : #'Material-Design-Lite-Widgets-Expansion' -} - -{ #category : #javascript } -MDLLazyExpansionStrategy >> customize: anExpansionPanelHeader in: anExpansionPanel on: html [ - anExpansionPanel isExpanded ifTrue: [ self switchToDisplayNoneStrategy ]. - - ^ currentStrategy customize: anExpansionPanelHeader in: anExpansionPanel on: html -] - -{ #category : #initialization } -MDLLazyExpansionStrategy >> initialize [ - super initialize. - currentStrategy := MDLAjaxExpansionStrategy new -] - -{ #category : #rendering } -MDLLazyExpansionStrategy >> renderExpansionPanel: anExpansionPanel contentOn: html [ - anExpansionPanel isExpanded ifTrue: [ self switchToDisplayNoneStrategy ]. - currentStrategy renderExpansionPanel: anExpansionPanel contentOn: html. - currentStrategy isAjaxExpansionStrategy ifTrue: [ self switchToDisplayNoneStrategy ] -] - -{ #category : #private } -MDLLazyExpansionStrategy >> switchToDisplayNoneStrategy [ - currentStrategy := MDLHideExpansionStrategy new -] +" +I am a lazy expansion strategy. +I combine the best from MDLHideExpansionStrategy and MDLAjaxExpansionStrategy to load the panel content only once when it is needed. + +That is to say, if the panel is initially rendered folded, the first time the user click the expansion panel to expand it, I will perform an AJAX call to ask the server to render the content. +Then, next times the user click on the expansion panel, I will behave as MDLHideExpansionStrategy. + +If the panel is initially rendered expanded, I behave exactly as MDLHideExpansionStrategy. +" +Class { + #name : #MDLLazyExpansionStrategy, + #superclass : #MDLExpansionStrategy, + #instVars : [ + 'currentStrategy' + ], + #category : #'Material-Design-Lite-Widgets-Expansion' +} + +{ #category : #javascript } +MDLLazyExpansionStrategy >> customize: anExpansionPanelHeader in: anExpansionPanel on: html [ + anExpansionPanel isExpanded ifTrue: [ self switchToDisplayNoneStrategy ]. + + ^ currentStrategy customize: anExpansionPanelHeader in: anExpansionPanel on: html +] + +{ #category : #initialization } +MDLLazyExpansionStrategy >> initialize [ + super initialize. + currentStrategy := MDLAjaxExpansionStrategy new +] + +{ #category : #rendering } +MDLLazyExpansionStrategy >> renderExpansionPanel: anExpansionPanel contentOn: html [ + anExpansionPanel isExpanded ifTrue: [ self switchToDisplayNoneStrategy ]. + currentStrategy renderExpansionPanel: anExpansionPanel contentOn: html. + currentStrategy isAjaxExpansionStrategy ifTrue: [ self switchToDisplayNoneStrategy ] +] + +{ #category : #private } +MDLLazyExpansionStrategy >> switchToDisplayNoneStrategy [ + currentStrategy := MDLHideExpansionStrategy new +] diff --git a/src/Material-Design-Lite-Widgets/MDLLinkingLayoutSection.class.st b/src/Material-Design-Lite-Widgets/MDLLinkingLayoutSection.class.st index d7f772f0..99b9aa2f 100644 --- a/src/Material-Design-Lite-Widgets/MDLLinkingLayoutSection.class.st +++ b/src/Material-Design-Lite-Widgets/MDLLinkingLayoutSection.class.st @@ -1,39 +1,39 @@ -Class { - #name : #MDLLinkingLayoutSection, - #superclass : #MDLAbstractLayoutSection, - #instVars : [ - 'links' - ], - #category : 'Material-Design-Lite-Widgets-Header' -} - -{ #category : #initialization } -MDLLinkingLayoutSection >> initialize [ - super initialize. - links := OrderedCollection new. -] - -{ #category : #accessing } -MDLLinkingLayoutSection >> links [ - ^ links -] - -{ #category : #accessing } -MDLLinkingLayoutSection >> links: anOrderedCollection [ - "This should be a collection of dictionaries Text -> callback" - links := anOrderedCollection -] - -{ #category : #rendering } -MDLLinkingLayoutSection >> renderLinksOn: html [ - self links - do: [ :aDictionary | - html - mdlNavigation: [ - aDictionary - keysAndValuesDo: [ :label :callback | - html mdlNavigationLink - callback: callback; - with: label ] ]. - html mdlLayoutSpacer ] -] +Class { + #name : #MDLLinkingLayoutSection, + #superclass : #MDLAbstractLayoutSection, + #instVars : [ + 'links' + ], + #category : 'Material-Design-Lite-Widgets-Header' +} + +{ #category : #initialization } +MDLLinkingLayoutSection >> initialize [ + super initialize. + links := OrderedCollection new. +] + +{ #category : #accessing } +MDLLinkingLayoutSection >> links [ + ^ links +] + +{ #category : #accessing } +MDLLinkingLayoutSection >> links: anOrderedCollection [ + "This should be a collection of dictionaries Text -> callback" + links := anOrderedCollection +] + +{ #category : #rendering } +MDLLinkingLayoutSection >> renderLinksOn: html [ + self links + do: [ :aDictionary | + html + mdlNavigation: [ + aDictionary + keysAndValuesDo: [ :label :callback | + html mdlNavigationLink + callback: callback; + with: label ] ]. + html mdlLayoutSpacer ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLListIconComponent.class.st b/src/Material-Design-Lite-Widgets/MDLListIconComponent.class.st index 35d0f608..b90fd2b6 100644 --- a/src/Material-Design-Lite-Widgets/MDLListIconComponent.class.st +++ b/src/Material-Design-Lite-Widgets/MDLListIconComponent.class.st @@ -1,57 +1,57 @@ -" -I am a simple component to display a MDL icon with an help text. My main purpose is to serve in a MDLNestedList to display a MDL icon. -" -Class { - #name : #MDLListIconComponent, - #superclass : #WAComponent, - #instVars : [ - 'label', - 'helpText' - ], - #category : 'Material-Design-Lite-Widgets-List' -} - -{ #category : #'instance creation' } -MDLListIconComponent class >> named: aString helpText: aTranslatedString [ - ^ self new - label: aString; - helpText: aTranslatedString; - yourself -] - -{ #category : #accessing } -MDLListIconComponent >> helpText [ - ^ helpText -] - -{ #category : #accessing } -MDLListIconComponent >> helpText: anObject [ - helpText := anObject -] - -{ #category : #accessing } -MDLListIconComponent >> label [ - ^ label -] - -{ #category : #accessing } -MDLListIconComponent >> label: anObject [ - label := anObject -] - -{ #category : #rendering } -MDLListIconComponent >> renderContentOn: html [ - | id | - id := html nextId. - html mdlIcon - id: id; - with: self label. - - (self helpText isNil or: [ self helpText isEmpty ]) - ifTrue: [ ^ self ]. - - html mdlTooltip - large; - for: id; - with: [ html text: self helpText ] -] +" +I am a simple component to display a MDL icon with an help text. My main purpose is to serve in a MDLNestedList to display a MDL icon. +" +Class { + #name : #MDLListIconComponent, + #superclass : #WAComponent, + #instVars : [ + 'label', + 'helpText' + ], + #category : 'Material-Design-Lite-Widgets-List' +} + +{ #category : #'instance creation' } +MDLListIconComponent class >> named: aString helpText: aTranslatedString [ + ^ self new + label: aString; + helpText: aTranslatedString; + yourself +] + +{ #category : #accessing } +MDLListIconComponent >> helpText [ + ^ helpText +] + +{ #category : #accessing } +MDLListIconComponent >> helpText: anObject [ + helpText := anObject +] + +{ #category : #accessing } +MDLListIconComponent >> label [ + ^ label +] + +{ #category : #accessing } +MDLListIconComponent >> label: anObject [ + label := anObject +] + +{ #category : #rendering } +MDLListIconComponent >> renderContentOn: html [ + | id | + id := html nextId. + html mdlIcon + id: id; + with: self label. + + (self helpText isNil or: [ self helpText isEmpty ]) + ifTrue: [ ^ self ]. + + html mdlTooltip + large; + for: id; + with: [ html text: self helpText ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLLoginCardWidget.class.st b/src/Material-Design-Lite-Widgets/MDLLoginCardWidget.class.st index 3298b80a..a220290f 100644 --- a/src/Material-Design-Lite-Widgets/MDLLoginCardWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLLoginCardWidget.class.st @@ -1,21 +1,21 @@ -" -I'm a login widget render in a card widget -" -Class { - #name : #MDLLoginCardWidget, - #superclass : #MDLLoginWidget, - #category : 'Material-Design-Lite-Widgets' -} - -{ #category : #rendering } -MDLLoginCardWidget >> renderContentOn: html [ - html - render: - (MDLCardWidget new - shadow: 2; - class: 'mdl-card__login-widget'; - class: self htmlClass; - title: titleLabel level: titleLevel; - addTextContainer: [ :canvas | super renderContentOn: canvas ]; - yourself) -] +" +I'm a login widget render in a card widget +" +Class { + #name : #MDLLoginCardWidget, + #superclass : #MDLLoginWidget, + #category : 'Material-Design-Lite-Widgets' +} + +{ #category : #rendering } +MDLLoginCardWidget >> renderContentOn: html [ + html + render: + (MDLCardWidget new + shadow: 2; + class: 'mdl-card__login-widget'; + class: self htmlClass; + title: titleLabel level: titleLevel; + addTextContainer: [ :canvas | super renderContentOn: canvas ]; + yourself) +] diff --git a/src/Material-Design-Lite-Widgets/MDLLoginDialogWidget.class.st b/src/Material-Design-Lite-Widgets/MDLLoginDialogWidget.class.st index 480bcbe1..0fb282aa 100644 --- a/src/Material-Design-Lite-Widgets/MDLLoginDialogWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLLoginDialogWidget.class.st @@ -1,76 +1,76 @@ -" -I represent the login widget but I am display in a dialog -" -Class { - #name : #MDLLoginDialogWidget, - #superclass : #MDLLoginWidget, - #instVars : [ - 'closeId', - 'openId', - 'signInTitleLabel', - 'signInButtonLabel' - ], - #category : 'Material-Design-Lite-Widgets' -} - -{ #category : #accessing } -MDLLoginDialogWidget >> closeId [ - ^ closeId -] - -{ #category : #accessing } -MDLLoginDialogWidget >> closeId: anObject [ - ^ closeId := anObject -] - -{ #category : #initialization } -MDLLoginDialogWidget >> initialize [ - super initialize. - signInTitleLabel := 'Sign In'. - signInButtonLabel := 'Sign In' -] - -{ #category : #accessing } -MDLLoginDialogWidget >> openId [ - ^ openId -] - -{ #category : #accessing } -MDLLoginDialogWidget >> openId: anObject [ - ^ openId := anObject -] - -{ #category : #rendering } -MDLLoginDialogWidget >> renderCancelButtonOn: html [ - html mdlButton - id: closeId; - raised; - with: cancelLabel -] - -{ #category : #rendering } -MDLLoginDialogWidget >> renderContentOn: html [ - self renderOpenButtonOn: html. - self renderLoginDialogOn: html -] - -{ #category : #rendering } -MDLLoginDialogWidget >> renderLoginDialogOn: html [ - html mdlDialog - openButtonId: openId; - closeButtonId: (closeId := html nextId); - with: [ html mdlDialogTitle - class: 'mdl-color--primary'; - with: signInTitleLabel. - html mdlDialogContent: [ super renderContentOn: html ] ] -] - -{ #category : #rendering } -MDLLoginDialogWidget >> renderOpenButtonOn: html [ - html mdlButton - id: (openId := html nextId); - raised; - colored; - rippleEffect; - with: signInButtonLabel -] +" +I represent the login widget but I am display in a dialog +" +Class { + #name : #MDLLoginDialogWidget, + #superclass : #MDLLoginWidget, + #instVars : [ + 'closeId', + 'openId', + 'signInTitleLabel', + 'signInButtonLabel' + ], + #category : 'Material-Design-Lite-Widgets' +} + +{ #category : #accessing } +MDLLoginDialogWidget >> closeId [ + ^ closeId +] + +{ #category : #accessing } +MDLLoginDialogWidget >> closeId: anObject [ + ^ closeId := anObject +] + +{ #category : #initialization } +MDLLoginDialogWidget >> initialize [ + super initialize. + signInTitleLabel := 'Sign In'. + signInButtonLabel := 'Sign In' +] + +{ #category : #accessing } +MDLLoginDialogWidget >> openId [ + ^ openId +] + +{ #category : #accessing } +MDLLoginDialogWidget >> openId: anObject [ + ^ openId := anObject +] + +{ #category : #rendering } +MDLLoginDialogWidget >> renderCancelButtonOn: html [ + html mdlButton + id: closeId; + raised; + with: cancelLabel +] + +{ #category : #rendering } +MDLLoginDialogWidget >> renderContentOn: html [ + self renderOpenButtonOn: html. + self renderLoginDialogOn: html +] + +{ #category : #rendering } +MDLLoginDialogWidget >> renderLoginDialogOn: html [ + html mdlDialog + openButtonId: openId; + closeButtonId: (closeId := html nextId); + with: [ html mdlDialogTitle + class: 'mdl-color--primary'; + with: signInTitleLabel. + html mdlDialogContent: [ super renderContentOn: html ] ] +] + +{ #category : #rendering } +MDLLoginDialogWidget >> renderOpenButtonOn: html [ + html mdlButton + id: (openId := html nextId); + raised; + colored; + rippleEffect; + with: signInButtonLabel +] diff --git a/src/Material-Design-Lite-Widgets/MDLLoginWidget.class.st b/src/Material-Design-Lite-Widgets/MDLLoginWidget.class.st index d39fe943..d461f204 100644 --- a/src/Material-Design-Lite-Widgets/MDLLoginWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLLoginWidget.class.st @@ -1,147 +1,147 @@ -" -A login widget which use a MDLCardWidget - -I'm ready to use, you just have to give me a callback with 2 arguments (login and password) and insert me in a form. -" -Class { - #name : #MDLLoginWidget, - #superclass : #MDLHighLevelWidget, - #instVars : [ - 'titleLabel', - 'titleLevel', - 'loginLabel', - 'passwordLabel', - 'login', - 'password', - 'submitLabel', - 'callback', - 'cancelLabel', - 'cancelCallback' - ], - #category : #'Material-Design-Lite-Widgets' -} - -{ #category : #accessing } -MDLLoginWidget >> callback: anObject [ - callback := anObject -] - -{ #category : #accessing } -MDLLoginWidget >> cancelCallback [ - ^ cancelCallback ifNil: [ cancelCallback := [ ] ] -] - -{ #category : #accessing } -MDLLoginWidget >> cancelCallback: anObject [ - cancelCallback := anObject -] - -{ #category : #accessing } -MDLLoginWidget >> cancelLabel: anObject [ - cancelLabel := anObject -] - -{ #category : #initialization } -MDLLoginWidget >> initialize [ - super initialize. - titleLabel := 'Please, sign in'. - titleLevel := 2. - loginLabel := 'Login'. - cancelLabel := 'Cancel'. - passwordLabel := 'Password'. - submitLabel := 'Sign In' -] - -{ #category : #accessing } -MDLLoginWidget >> login [ - ^ login -] - -{ #category : #accessing } -MDLLoginWidget >> login: anObject [ - login := anObject -] - -{ #category : #rendering } -MDLLoginWidget >> loginInputWidget [ - ^ MDLTextFieldWidget new - beFloatingLabel; - on: #login of: self; - label: loginLabel; - yourself -] - -{ #category : #accessing } -MDLLoginWidget >> loginLabel: anObject [ - loginLabel := anObject -] - -{ #category : #accessing } -MDLLoginWidget >> password [ - ^ password -] - -{ #category : #accessing } -MDLLoginWidget >> password: anObject [ - password := anObject -] - -{ #category : #rendering } -MDLLoginWidget >> passwordInputWidget [ - ^ MDLTextFieldWidget new beFloatingLabel - type: 'password'; - on: #password of: self; - label: passwordLabel; - yourself -] - -{ #category : #accessing } -MDLLoginWidget >> passwordLabel: anObject [ - passwordLabel := anObject -] - -{ #category : #rendering } -MDLLoginWidget >> renderCancelButtonOn: html [ - html anchor - class: 'mdl-button mdl-js-button mdl-button--raised'; - callback: self cancelCallback; - with: cancelLabel -] - -{ #category : #rendering } -MDLLoginWidget >> renderContentOn: html [ - self renderFieldsOn: html. - self renderSubmitButtonOn: html. - self renderCancelButtonOn: html -] - -{ #category : #rendering } -MDLLoginWidget >> renderFieldsOn: html [ - html render: self loginInputWidget. - html render: self passwordInputWidget -] - -{ #category : #rendering } -MDLLoginWidget >> renderSubmitButtonOn: html [ - html mdlButton - raised; - accentColor; - beSubmit; - callback: [ callback value: login value: password ]; - with: submitLabel -] - -{ #category : #accessing } -MDLLoginWidget >> submitLabel: anObject [ - submitLabel := anObject -] - -{ #category : #accessing } -MDLLoginWidget >> titleLabel: anObject [ - titleLabel := anObject -] - -{ #category : #accessing } -MDLLoginWidget >> titleLevel: anObject [ - titleLevel := anObject -] +" +A login widget which use a MDLCardWidget + +I'm ready to use, you just have to give me a callback with 2 arguments (login and password) and insert me in a form. +" +Class { + #name : #MDLLoginWidget, + #superclass : #MDLHighLevelWidget, + #instVars : [ + 'titleLabel', + 'titleLevel', + 'loginLabel', + 'passwordLabel', + 'login', + 'password', + 'submitLabel', + 'callback', + 'cancelLabel', + 'cancelCallback' + ], + #category : #'Material-Design-Lite-Widgets' +} + +{ #category : #accessing } +MDLLoginWidget >> callback: anObject [ + callback := anObject +] + +{ #category : #accessing } +MDLLoginWidget >> cancelCallback [ + ^ cancelCallback ifNil: [ cancelCallback := [ ] ] +] + +{ #category : #accessing } +MDLLoginWidget >> cancelCallback: anObject [ + cancelCallback := anObject +] + +{ #category : #accessing } +MDLLoginWidget >> cancelLabel: anObject [ + cancelLabel := anObject +] + +{ #category : #initialization } +MDLLoginWidget >> initialize [ + super initialize. + titleLabel := 'Please, sign in'. + titleLevel := 2. + loginLabel := 'Login'. + cancelLabel := 'Cancel'. + passwordLabel := 'Password'. + submitLabel := 'Sign In' +] + +{ #category : #accessing } +MDLLoginWidget >> login [ + ^ login +] + +{ #category : #accessing } +MDLLoginWidget >> login: anObject [ + login := anObject +] + +{ #category : #rendering } +MDLLoginWidget >> loginInputWidget [ + ^ MDLTextFieldWidget new + beFloatingLabel; + on: #login of: self; + label: loginLabel; + yourself +] + +{ #category : #accessing } +MDLLoginWidget >> loginLabel: anObject [ + loginLabel := anObject +] + +{ #category : #accessing } +MDLLoginWidget >> password [ + ^ password +] + +{ #category : #accessing } +MDLLoginWidget >> password: anObject [ + password := anObject +] + +{ #category : #rendering } +MDLLoginWidget >> passwordInputWidget [ + ^ MDLTextFieldWidget new beFloatingLabel + type: 'password'; + on: #password of: self; + label: passwordLabel; + yourself +] + +{ #category : #accessing } +MDLLoginWidget >> passwordLabel: anObject [ + passwordLabel := anObject +] + +{ #category : #rendering } +MDLLoginWidget >> renderCancelButtonOn: html [ + html anchor + class: 'mdl-button mdl-js-button mdl-button--raised'; + callback: self cancelCallback; + with: cancelLabel +] + +{ #category : #rendering } +MDLLoginWidget >> renderContentOn: html [ + self renderFieldsOn: html. + self renderSubmitButtonOn: html. + self renderCancelButtonOn: html +] + +{ #category : #rendering } +MDLLoginWidget >> renderFieldsOn: html [ + html render: self loginInputWidget. + html render: self passwordInputWidget +] + +{ #category : #rendering } +MDLLoginWidget >> renderSubmitButtonOn: html [ + html mdlButton + raised; + accentColor; + beSubmit; + callback: [ callback value: login value: password ]; + with: submitLabel +] + +{ #category : #accessing } +MDLLoginWidget >> submitLabel: anObject [ + submitLabel := anObject +] + +{ #category : #accessing } +MDLLoginWidget >> titleLabel: anObject [ + titleLabel := anObject +] + +{ #category : #accessing } +MDLLoginWidget >> titleLevel: anObject [ + titleLevel := anObject +] diff --git a/src/Material-Design-Lite-Widgets/MDLMegaFooterLinksList.class.st b/src/Material-Design-Lite-Widgets/MDLMegaFooterLinksList.class.st index 5fee0a2c..8289efa0 100644 --- a/src/Material-Design-Lite-Widgets/MDLMegaFooterLinksList.class.st +++ b/src/Material-Design-Lite-Widgets/MDLMegaFooterLinksList.class.st @@ -1,11 +1,11 @@ -Class { - #name : #MDLMegaFooterLinksList, - #superclass : #MDLAbstractFooterLinksList, - #category : 'Material-Design-Lite-Widgets-Footer' -} - -{ #category : #'as yet unclassified' } -MDLMegaFooterLinksList >> renderLinksListOn: html [ - html mdlFooterLinkList: [ - self renderLinksOn: html ] -] +Class { + #name : #MDLMegaFooterLinksList, + #superclass : #MDLAbstractFooterLinksList, + #category : 'Material-Design-Lite-Widgets-Footer' +} + +{ #category : #'as yet unclassified' } +MDLMegaFooterLinksList >> renderLinksListOn: html [ + html mdlFooterLinkList: [ + self renderLinksOn: html ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLMenuButtonWidget.class.st b/src/Material-Design-Lite-Widgets/MDLMenuButtonWidget.class.st index 85a4b81c..02f446b5 100644 --- a/src/Material-Design-Lite-Widgets/MDLMenuButtonWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLMenuButtonWidget.class.st @@ -1,276 +1,276 @@ -" -Description --------------------- - -I am a mdl button that expand a menu to choose an item. When an item is selected I will refresh the page. - -Examples --------------------- - - (MDLMenuButtonWidget - possibilities: #('Guillaume' 'Kévin' 'Anne' 'Cyril' 'Olivier' 'Yann') - label: #asString - action: [ :o | Transcript crShow: o ] - choosingText: 'Select an user' - description: 'Choose a user to log into the Transcript') - sortBlock: [ :a :b | a < b ]; - yourself - -Internal Representation and Key Implementation Points. --------------------- - - Instance Variables - action: Callback taking the selected element as parameter - buttonContent: The content of the button. Can be a string or a block. The block takes an html canvas as parameter - description: Tooltip to show on the button - objectsPossibilities: Collection of object to select from - selectedObject: Selected object by default - sortBlock: A block to sort the elements of the menu - textBlock: A block taking a possible object as parameter and returning a string to display on the menu - -" -Class { - #name : #MDLMenuButtonWidget, - #superclass : #MDLWidget, - #instVars : [ - 'textBlock', - 'selectedObject', - 'objectsPossibilities', - 'description', - 'action', - 'sortBlock', - 'buttonContent', - 'descriptionPosition' - ], - #category : #'Material-Design-Lite-Widgets-Menu' -} - -{ #category : #'instance creation' } -MDLMenuButtonWidget class >> possibilities: aCollectionOfObjects label: aLabelBlock action: anAction choosingText: aText [ - ^ self possibilities: aCollectionOfObjects label: aLabelBlock action: anAction choosingText: aText description: nil -] - -{ #category : #'instance creation' } -MDLMenuButtonWidget class >> possibilities: aCollectionOfObjects label: aLabelBlock action: anAction choosingText: aText description: aDescriptionValuable [ - ^ self - possibilities: aCollectionOfObjects - label: aLabelBlock - action: anAction - selectedObject: nil - choosingText: aText - description: aDescriptionValuable -] - -{ #category : #'instance creation' } -MDLMenuButtonWidget class >> possibilities: aCollectionOfObjects label: aLabelBlock action: anAction selectedObject: anObjectOrNil choosingText: aText [ - ^ self - possibilities: aCollectionOfObjects - label: aLabelBlock - action: anAction - selectedObject: anObjectOrNil - choosingText: aText - description: nil -] - -{ #category : #'instance creation' } -MDLMenuButtonWidget class >> possibilities: aCollectionOfObjects label: aLabelBlock action: anAction selectedObject: anObjectOrNil choosingText: aText description: aDescriptionValuable [ - ^ self new - choosingText: aText; - textBlock: aLabelBlock; - selectedObject: anObjectOrNil; - description: aDescriptionValuable; - action: anAction; - objectsPossibilities: aCollectionOfObjects; - yourself -] - -{ #category : #accessing } -MDLMenuButtonWidget >> action [ - ^ action -] - -{ #category : #accessing } -MDLMenuButtonWidget >> action: anObject [ - action := anObject -] - -{ #category : #private } -MDLMenuButtonWidget >> actionWith: anObject [ - self action ifNotNil: [ :block | block value: anObject] -] - -{ #category : #accessing } -MDLMenuButtonWidget >> buttonContent [ - ^ buttonContent ifNil: [ buttonContent := 'choose' ] -] - -{ #category : #accessing } -MDLMenuButtonWidget >> buttonContent: aBlockOrString [ - buttonContent := aBlockOrString -] - -{ #category : #accessing } -MDLMenuButtonWidget >> choosingText [ - "This method is to keep backward compatibility with old API. This might be suppress with the next major release." - - self buttonContent isString ifTrue: [ ^ self buttonContent ]. - - self error: 'This button was not configured to render a string but was configured with a block' -] - -{ #category : #accessing } -MDLMenuButtonWidget >> choosingText: aString [ - "This method is to keep backward compatibility with old API. This might be suppress with the next major release." - - self buttonContent: aString -] - -{ #category : #accessing } -MDLMenuButtonWidget >> description [ - ^ description -] - -{ #category : #accessing } -MDLMenuButtonWidget >> description: anObject [ - description := anObject -] - -{ #category : #options } -MDLMenuButtonWidget >> descriptionAtBottom [ - "Sets the description of the menu at its bottom." - self descriptionPosition: #bottom -] - -{ #category : #options } -MDLMenuButtonWidget >> descriptionAtLeft [ - "Sets the description of the menu at its left." - self descriptionPosition: #left -] - -{ #category : #options } -MDLMenuButtonWidget >> descriptionAtRight [ - "Sets the description of the menu at its right." - self descriptionPosition: #right -] - -{ #category : #options } -MDLMenuButtonWidget >> descriptionAtTop [ - "Sets the description of the menu at its top." - self descriptionPosition: #top -] - -{ #category : #accessing } -MDLMenuButtonWidget >> descriptionPosition [ - ^ descriptionPosition ifNil: [ descriptionPosition := #bottom ] -] - -{ #category : #accessing } -MDLMenuButtonWidget >> descriptionPosition: anObject [ - descriptionPosition := anObject -] - -{ #category : #private } -MDLMenuButtonWidget >> labelFor: anObject [ - ^ self textBlock ifNil: [ anObject asString ] ifNotNil: [ :tb | tb cull: anObject ] -] - -{ #category : #accessing } -MDLMenuButtonWidget >> objectsPossibilities [ - ^ objectsPossibilities -] - -{ #category : #accessing } -MDLMenuButtonWidget >> objectsPossibilities: anObject [ - objectsPossibilities := anObject -] - -{ #category : #accessing } -MDLMenuButtonWidget >> objectsPossibilitiesWithLabel [ - ^ (self objectsPossibilities collect: [ :anObject | (self labelFor: anObject) -> anObject ]) sorted: self sortBlock -] - -{ #category : #rendering } -MDLMenuButtonWidget >> renderButtonContentOn: html [ - self buttonContent isString - ifTrue: [ html render: self buttonContent ] - ifFalse: [ self buttonContent cull: html ] -] - -{ #category : #rendering } -MDLMenuButtonWidget >> renderButtonOn: html [ - html div - id: self id; - class: 'menuButtonWidgetButton mdl-button mdl-js-button menuButtonWidgetButton'; - disabled: self objectsPossibilities isEmpty; - with: [ self selectedObject - ifNil: [ self renderButtonContentOn: html ] - ifNotNil: [ :anObject | html text: (self labelFor: anObject) ]. - html mdlIcon: 'arrow_drop_down' ] -] - -{ #category : #rendering } -MDLMenuButtonWidget >> renderContentOn: html [ - self ensureId: html. - self renderButtonOn: html. - self renderMenuOn: html. - self renderTooltipOn: html. -] - -{ #category : #rendering } -MDLMenuButtonWidget >> renderMenuItemOn: html withAssociation: anAssociation [ - html - mdlMenuItem: [ - html anchor - callback: [ self actionWith: anAssociation value ]; - with: [ html text: anAssociation key ] ] -] - -{ #category : #rendering } -MDLMenuButtonWidget >> renderMenuOn: html [ - html mdlMenu - bottomLeft; - for: self id; - class: 'menuButtonWidgetMenu'; - with: [ self objectsPossibilitiesWithLabel do: [ :anAssociation | self renderMenuItemOn: html withAssociation: anAssociation ] ] -] - -{ #category : #rendering } -MDLMenuButtonWidget >> renderTooltipOn: html [ - self description ifNil: [ ^ self ]. - - html mdlTooltip - for: self id; - large; - position: self descriptionPosition; - with: self description -] - -{ #category : #accessing } -MDLMenuButtonWidget >> selectedObject [ - ^ selectedObject value -] - -{ #category : #accessing } -MDLMenuButtonWidget >> selectedObject: anObject [ - selectedObject := anObject -] - -{ #category : #accessing } -MDLMenuButtonWidget >> sortBlock [ - ^ sortBlock ifNil: [ sortBlock := [ :a :b | a <= b ] ] -] - -{ #category : #accessing } -MDLMenuButtonWidget >> sortBlock: anObject [ - sortBlock := anObject -] - -{ #category : #accessing } -MDLMenuButtonWidget >> textBlock [ - ^ textBlock -] - -{ #category : #accessing } -MDLMenuButtonWidget >> textBlock: anObject [ - textBlock := anObject -] +" +Description +-------------------- + +I am a mdl button that expand a menu to choose an item. When an item is selected I will refresh the page. + +Examples +-------------------- + + (MDLMenuButtonWidget + possibilities: #('Guillaume' 'Kévin' 'Anne' 'Cyril' 'Olivier' 'Yann') + label: #asString + action: [ :o | Transcript crShow: o ] + choosingText: 'Select an user' + description: 'Choose a user to log into the Transcript') + sortBlock: [ :a :b | a < b ]; + yourself + +Internal Representation and Key Implementation Points. +-------------------- + + Instance Variables + action: Callback taking the selected element as parameter + buttonContent: The content of the button. Can be a string or a block. The block takes an html canvas as parameter + description: Tooltip to show on the button + objectsPossibilities: Collection of object to select from + selectedObject: Selected object by default + sortBlock: A block to sort the elements of the menu + textBlock: A block taking a possible object as parameter and returning a string to display on the menu + +" +Class { + #name : #MDLMenuButtonWidget, + #superclass : #MDLWidget, + #instVars : [ + 'textBlock', + 'selectedObject', + 'objectsPossibilities', + 'description', + 'action', + 'sortBlock', + 'buttonContent', + 'descriptionPosition' + ], + #category : #'Material-Design-Lite-Widgets-Menu' +} + +{ #category : #'instance creation' } +MDLMenuButtonWidget class >> possibilities: aCollectionOfObjects label: aLabelBlock action: anAction choosingText: aText [ + ^ self possibilities: aCollectionOfObjects label: aLabelBlock action: anAction choosingText: aText description: nil +] + +{ #category : #'instance creation' } +MDLMenuButtonWidget class >> possibilities: aCollectionOfObjects label: aLabelBlock action: anAction choosingText: aText description: aDescriptionValuable [ + ^ self + possibilities: aCollectionOfObjects + label: aLabelBlock + action: anAction + selectedObject: nil + choosingText: aText + description: aDescriptionValuable +] + +{ #category : #'instance creation' } +MDLMenuButtonWidget class >> possibilities: aCollectionOfObjects label: aLabelBlock action: anAction selectedObject: anObjectOrNil choosingText: aText [ + ^ self + possibilities: aCollectionOfObjects + label: aLabelBlock + action: anAction + selectedObject: anObjectOrNil + choosingText: aText + description: nil +] + +{ #category : #'instance creation' } +MDLMenuButtonWidget class >> possibilities: aCollectionOfObjects label: aLabelBlock action: anAction selectedObject: anObjectOrNil choosingText: aText description: aDescriptionValuable [ + ^ self new + choosingText: aText; + textBlock: aLabelBlock; + selectedObject: anObjectOrNil; + description: aDescriptionValuable; + action: anAction; + objectsPossibilities: aCollectionOfObjects; + yourself +] + +{ #category : #accessing } +MDLMenuButtonWidget >> action [ + ^ action +] + +{ #category : #accessing } +MDLMenuButtonWidget >> action: anObject [ + action := anObject +] + +{ #category : #private } +MDLMenuButtonWidget >> actionWith: anObject [ + self action ifNotNil: [ :block | block value: anObject] +] + +{ #category : #accessing } +MDLMenuButtonWidget >> buttonContent [ + ^ buttonContent ifNil: [ buttonContent := 'choose' ] +] + +{ #category : #accessing } +MDLMenuButtonWidget >> buttonContent: aBlockOrString [ + buttonContent := aBlockOrString +] + +{ #category : #accessing } +MDLMenuButtonWidget >> choosingText [ + "This method is to keep backward compatibility with old API. This might be suppress with the next major release." + + self buttonContent isString ifTrue: [ ^ self buttonContent ]. + + self error: 'This button was not configured to render a string but was configured with a block' +] + +{ #category : #accessing } +MDLMenuButtonWidget >> choosingText: aString [ + "This method is to keep backward compatibility with old API. This might be suppress with the next major release." + + self buttonContent: aString +] + +{ #category : #accessing } +MDLMenuButtonWidget >> description [ + ^ description +] + +{ #category : #accessing } +MDLMenuButtonWidget >> description: anObject [ + description := anObject +] + +{ #category : #options } +MDLMenuButtonWidget >> descriptionAtBottom [ + "Sets the description of the menu at its bottom." + self descriptionPosition: #bottom +] + +{ #category : #options } +MDLMenuButtonWidget >> descriptionAtLeft [ + "Sets the description of the menu at its left." + self descriptionPosition: #left +] + +{ #category : #options } +MDLMenuButtonWidget >> descriptionAtRight [ + "Sets the description of the menu at its right." + self descriptionPosition: #right +] + +{ #category : #options } +MDLMenuButtonWidget >> descriptionAtTop [ + "Sets the description of the menu at its top." + self descriptionPosition: #top +] + +{ #category : #accessing } +MDLMenuButtonWidget >> descriptionPosition [ + ^ descriptionPosition ifNil: [ descriptionPosition := #bottom ] +] + +{ #category : #accessing } +MDLMenuButtonWidget >> descriptionPosition: anObject [ + descriptionPosition := anObject +] + +{ #category : #private } +MDLMenuButtonWidget >> labelFor: anObject [ + ^ self textBlock ifNil: [ anObject asString ] ifNotNil: [ :tb | tb cull: anObject ] +] + +{ #category : #accessing } +MDLMenuButtonWidget >> objectsPossibilities [ + ^ objectsPossibilities +] + +{ #category : #accessing } +MDLMenuButtonWidget >> objectsPossibilities: anObject [ + objectsPossibilities := anObject +] + +{ #category : #accessing } +MDLMenuButtonWidget >> objectsPossibilitiesWithLabel [ + ^ (self objectsPossibilities collect: [ :anObject | (self labelFor: anObject) -> anObject ]) sorted: self sortBlock +] + +{ #category : #rendering } +MDLMenuButtonWidget >> renderButtonContentOn: html [ + self buttonContent isString + ifTrue: [ html render: self buttonContent ] + ifFalse: [ self buttonContent cull: html ] +] + +{ #category : #rendering } +MDLMenuButtonWidget >> renderButtonOn: html [ + html div + id: self id; + class: 'menuButtonWidgetButton mdl-button mdl-js-button menuButtonWidgetButton'; + disabled: self objectsPossibilities isEmpty; + with: [ self selectedObject + ifNil: [ self renderButtonContentOn: html ] + ifNotNil: [ :anObject | html text: (self labelFor: anObject) ]. + html mdlIcon: 'arrow_drop_down' ] +] + +{ #category : #rendering } +MDLMenuButtonWidget >> renderContentOn: html [ + self ensureId: html. + self renderButtonOn: html. + self renderMenuOn: html. + self renderTooltipOn: html. +] + +{ #category : #rendering } +MDLMenuButtonWidget >> renderMenuItemOn: html withAssociation: anAssociation [ + html + mdlMenuItem: [ + html anchor + callback: [ self actionWith: anAssociation value ]; + with: [ html text: anAssociation key ] ] +] + +{ #category : #rendering } +MDLMenuButtonWidget >> renderMenuOn: html [ + html mdlMenu + bottomLeft; + for: self id; + class: 'menuButtonWidgetMenu'; + with: [ self objectsPossibilitiesWithLabel do: [ :anAssociation | self renderMenuItemOn: html withAssociation: anAssociation ] ] +] + +{ #category : #rendering } +MDLMenuButtonWidget >> renderTooltipOn: html [ + self description ifNil: [ ^ self ]. + + html mdlTooltip + for: self id; + large; + position: self descriptionPosition; + with: self description +] + +{ #category : #accessing } +MDLMenuButtonWidget >> selectedObject [ + ^ selectedObject value +] + +{ #category : #accessing } +MDLMenuButtonWidget >> selectedObject: anObject [ + selectedObject := anObject +] + +{ #category : #accessing } +MDLMenuButtonWidget >> sortBlock [ + ^ sortBlock ifNil: [ sortBlock := [ :a :b | a <= b ] ] +] + +{ #category : #accessing } +MDLMenuButtonWidget >> sortBlock: anObject [ + sortBlock := anObject +] + +{ #category : #accessing } +MDLMenuButtonWidget >> textBlock [ + ^ textBlock +] + +{ #category : #accessing } +MDLMenuButtonWidget >> textBlock: anObject [ + textBlock := anObject +] diff --git a/src/Material-Design-Lite-Widgets/MDLMiniFooterLinksList.class.st b/src/Material-Design-Lite-Widgets/MDLMiniFooterLinksList.class.st index 2008fe7e..49d94b2d 100644 --- a/src/Material-Design-Lite-Widgets/MDLMiniFooterLinksList.class.st +++ b/src/Material-Design-Lite-Widgets/MDLMiniFooterLinksList.class.st @@ -1,11 +1,11 @@ -Class { - #name : #MDLMiniFooterLinksList, - #superclass : #MDLAbstractFooterLinksList, - #category : 'Material-Design-Lite-Widgets-Footer' -} - -{ #category : #'as yet unclassified' } -MDLMiniFooterLinksList >> renderLinksListOn: html [ - html mdlMiniFooterLinkList: [ - self renderLinksOn: html ] -] +Class { + #name : #MDLMiniFooterLinksList, + #superclass : #MDLAbstractFooterLinksList, + #category : 'Material-Design-Lite-Widgets-Footer' +} + +{ #category : #'as yet unclassified' } +MDLMiniFooterLinksList >> renderLinksListOn: html [ + html mdlMiniFooterLinkList: [ + self renderLinksOn: html ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLNavigationLinkWithIconComponent.class.st b/src/Material-Design-Lite-Widgets/MDLNavigationLinkWithIconComponent.class.st index 7ca8131d..efb4a265 100644 --- a/src/Material-Design-Lite-Widgets/MDLNavigationLinkWithIconComponent.class.st +++ b/src/Material-Design-Lite-Widgets/MDLNavigationLinkWithIconComponent.class.st @@ -1,54 +1,54 @@ -Class { - #name : #MDLNavigationLinkWithIconComponent, - #superclass : #WAComponent, - #instVars : [ - 'icon', - 'label', - 'callback', - 'iconUrl' - ], - #category : 'Material-Design-Lite-Widgets' -} - -{ #category : #accessing } -MDLNavigationLinkWithIconComponent >> callback [ - ^ callback -] - -{ #category : #accessing } -MDLNavigationLinkWithIconComponent >> callback: anObject [ - callback := anObject -] - -{ #category : #accessing } -MDLNavigationLinkWithIconComponent >> icon [ - ^ icon -] - -{ #category : #accessing } -MDLNavigationLinkWithIconComponent >> iconUrl: anObject [ - iconUrl := anObject -] - -{ #category : #accessing } -MDLNavigationLinkWithIconComponent >> label [ - ^ label -] - -{ #category : #accessing } -MDLNavigationLinkWithIconComponent >> label: anObject [ - label := anObject -] - -{ #category : #rendering } -MDLNavigationLinkWithIconComponent >> renderContentOn: html [ - html mdlNavigationLink - style: 'margin: 8px 16px'; - callback: callback; - with: [ html - div: [ html image - url: (iconUrl);" - url: (MDLDemoLibrary urlOf: icon);" - style: 'height: 46px; width: 46px; margin: 0px 10px;'. - html span: label ] ] -] +Class { + #name : #MDLNavigationLinkWithIconComponent, + #superclass : #WAComponent, + #instVars : [ + 'icon', + 'label', + 'callback', + 'iconUrl' + ], + #category : 'Material-Design-Lite-Widgets' +} + +{ #category : #accessing } +MDLNavigationLinkWithIconComponent >> callback [ + ^ callback +] + +{ #category : #accessing } +MDLNavigationLinkWithIconComponent >> callback: anObject [ + callback := anObject +] + +{ #category : #accessing } +MDLNavigationLinkWithIconComponent >> icon [ + ^ icon +] + +{ #category : #accessing } +MDLNavigationLinkWithIconComponent >> iconUrl: anObject [ + iconUrl := anObject +] + +{ #category : #accessing } +MDLNavigationLinkWithIconComponent >> label [ + ^ label +] + +{ #category : #accessing } +MDLNavigationLinkWithIconComponent >> label: anObject [ + label := anObject +] + +{ #category : #rendering } +MDLNavigationLinkWithIconComponent >> renderContentOn: html [ + html mdlNavigationLink + style: 'margin: 8px 16px'; + callback: callback; + with: [ html + div: [ html image + url: (iconUrl);" + url: (MDLDemoLibrary urlOf: icon);" + style: 'height: 46px; width: 46px; margin: 0px 10px;'. + html span: label ] ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLNestedList.class.st b/src/Material-Design-Lite-Widgets/MDLNestedList.class.st index f69a84a0..6c438ae2 100644 --- a/src/Material-Design-Lite-Widgets/MDLNestedList.class.st +++ b/src/Material-Design-Lite-Widgets/MDLNestedList.class.st @@ -1,651 +1,651 @@ -" -I am a component use to display nicely a list of elements. -I am also able to display nested list as a tree. - -Description ------------------- - -I display a list of elements and I manage most of the css needed to make a good rendering. -For the icon check MDLListIconComponent or give any component you want. - -For more info you can test the demo. - -Public API and Key Messages ------------------- - -- #actionBlock: aBlock Allow to set an action to execute on click -- #elements: aCollection Is the list of elements to display -- #children: aBlock Return for each element his childrens -- #format: aBlock Is a block that take an element and return the element with the right format -- #selectedEntity: anElement If the element in parameter is in the list, it zill be highlighted -- #helpBlock: aBlock Allow to add a fly by help on elements -- #iconBlock: aBlock Allow to add an icon on each line - -Example ------------------- - - (SYNListComponent elements: #(1 34 56 89) children: [ :number | number even ifTrue: [ {(number + 1) . (number + 3) } ] ifFalse: [ #() ] ] ]) - actionBlock: [ :elem | Transcript crShow: elem asString ]; - format: [ :elem | elem asString , '%' ]; - selectedEntity: 34; - yourself - -Internal Representation and Key Implementation Points. ------------------- - - Instance Variables - actionBlock: A block executed when an element is selected - children: A block that return the list of children of an element - elements: A collection of elements to display - format: A block executed to format an element - selectedEntity: An element that need to be highlighted in the list - helpBlock: A block that return an optional fly-by-felp for an element - iconBlock: A block thet return an optional SYNListIconComponent for a line of the list -" -Class { - #name : #MDLNestedList, - #superclass : #MDLWidget, - #instVars : [ - 'elements', - 'entryCustomizationHook', - 'filteredElements', - 'selectedEntity', - 'dragAndDropBlock', - 'displayResearchField', - 'displayResearchFilter', - 'filter', - 'listStyle', - 'onLoadHook', - 'listMaxSize', - 'obtainedTreesCache', - 'strategy' - ], - #category : #'Material-Design-Lite-Widgets-List' -} - -{ #category : #'instance creation' } -MDLNestedList class >> elements: aCollection [ - ^ self new - elements: aCollection; - yourself -] - -{ #category : #'instance creation' } -MDLNestedList class >> elements: aCollection children: aBlockOrSymbole [ - ^ (self elements: aCollection) - childrenBlock: aBlockOrSymbole; - yourself -] - -{ #category : #accessing } -MDLNestedList >> actionBlock [ - ^ self strategy actionBlock -] - -{ #category : #accessing } -MDLNestedList >> actionBlock: aBlock [ - self - assert: aBlock argumentCount = 1 - description: - 'This block must take one argument; it will be the clicked entity in the list'. - self strategy actionBlock: aBlock -] - -{ #category : #private } -MDLNestedList >> at: anInteger ifPresent: aBlockClosure [ - aBlockClosure value: (self filteredElements at: anInteger) -] - -{ #category : #accessing } -MDLNestedList >> beCompact [ - self listStyle: #compact -] - -{ #category : #accessing } -MDLNestedList >> beStandard [ - self listStyle: #standard -] - -{ #category : #accessing } -MDLNestedList >> children: aBlockOrSymbol [ - self childrenBlock: aBlockOrSymbol -] - -{ #category : #accessing } -MDLNestedList >> childrenBlock [ - ^ self strategy childrenBlock - ifNil: [ self strategy childrenBlock: [ :item | #() ]. - self strategy childrenBlock ] -] - -{ #category : #accessing } -MDLNestedList >> childrenBlock: anObject [ - self strategy childrenBlock: anObject -] - -{ #category : #accessing } -MDLNestedList >> childrenSortBlock [ - ^ self strategy childrenSortBlock -] - -{ #category : #accessing } -MDLNestedList >> childrenSortBlock: aBlock [ - self strategy childrenSortBlock: aBlock -] - -{ #category : #javascript } -MDLNestedList >> defineChildrenCallbackOn: aDiv [ - ^ aDiv - storeCallback: - (WAValueCallback - on: [ :intervalRequest | - self requestContext - respond: [ :response | - self - printSublistFor: intervalRequest - context: aDiv canvas context - on: - (response - doNotCache; - contentType: WAMimeType textHtml; - stream) ] ]) -] - -{ #category : #javascript } -MDLNestedList >> defineScrollCallbackOn: aDiv [ - ^ aDiv - storeCallback: - (WAValueCallback - on: [ :intervalRequest | - | interval | - interval := $: split: intervalRequest. - self requestContext - respond: [ :response | - self - printHtmlForElementsFrom: interval first asNumber - to: interval last asNumber - context: aDiv canvas context - on: - (response - doNotCache; - contentType: WAMimeType textHtml; - stream) ] ]) -] - -{ #category : #accessing } -MDLNestedList >> displayResearchField [ - ^ displayResearchField -] - -{ #category : #accessing } -MDLNestedList >> displayResearchField: aBoolean [ - displayResearchField := aBoolean -] - -{ #category : #accessing } -MDLNestedList >> displayResearchFilter [ - ^ displayResearchFilter -] - -{ #category : #accessing } -MDLNestedList >> displayResearchFilter: aFilter [ - aFilter - ifEmpty: [ - displayResearchFilter := nil. - filteredElements := #() ] - ifNotEmpty: [ - displayResearchFilter := aFilter. - filteredElements := self filter - selectMatchingFrom: self elements - format: self format - with: self displayResearchFilter ] -] - -{ #category : #accessing } -MDLNestedList >> dragAndDropBlock [ - ^ dragAndDropBlock -] - -{ #category : #accessing } -MDLNestedList >> dragAndDropBlock: anObject [ - dragAndDropBlock := anObject -] - -{ #category : #draggable } -MDLNestedList >> draggableMechanism: html forDiv: div [ - self hasDraggableItems - ifTrue: [ - html - script: - (self - draggableScript: html actionUrl - cb: - (div - storeCallback: - (WAValueCallback - on: [ :drag | - | dragValues | - dragValues := drag substrings: ';'. - self dragAndDropBlock - value: (self obtainElementForPath: dragValues first) - value: (self obtainElementForPath: dragValues second) ]))) ] -] - -{ #category : #draggable } -MDLNestedList >> draggableScript:url cb: draggableCb [ - ^ 'function dragListItem(ev, index) { - ev.dataTransfer.setData("sourceIndex", index); -} - - -function dropListItem(ev, index){ - var source = ev.dataTransfer.getData("sourceIndex"); - var target = index; - if(source == target) console.log("Sleep"); - else post("' , url asString , '",{' , draggableCb - , - ': source + ";" + target});; -}' -] - -{ #category : #accessing } -MDLNestedList >> elements [ - ^ elements value -] - -{ #category : #accessing } -MDLNestedList >> elements: anObject [ - elements := anObject. - "reinitialize the filter when list change" - self displayResearchFilter: '' -] - -{ #category : #accessing } -MDLNestedList >> elementsDisplayList [ - | start overflow | - ^ self filteredElements size <= self listMaxSize - ifTrue: [ self filteredElements ] - ifFalse: [ start := self indexOfRootElementContainingSelectedEntity - (self listMaxSize / 2) max: 1. - overflow := 0 max: start + self listMaxSize - self filteredElements size. - self filteredElements copyFrom: start - overflow to: start + self listMaxSize - 1 - overflow ] -] - -{ #category : #accessing } -MDLNestedList >> entryCustomizationHook [ - ^ entryCustomizationHook -] - -{ #category : #accessing } -MDLNestedList >> entryCustomizationHook: anObject [ - entryCustomizationHook := anObject -] - -{ #category : #accessing } -MDLNestedList >> filter [ - ^ filter -] - -{ #category : #accessing } -MDLNestedList >> filter: anObject [ - filter := anObject -] - -{ #category : #accessing } -MDLNestedList >> filterInsensitiveBeginsWith [ - self filter: MDLInsensitiveBeginsWithFilter -] - -{ #category : #accessing } -MDLNestedList >> filterInsensitiveSubstring [ - self filter: MDLInsensitiveSubstringFilter -] - -{ #category : #accessing } -MDLNestedList >> filterPseudoRegex [ - self filter: MDLPseudoRegexFilter -] - -{ #category : #accessing } -MDLNestedList >> filterSensitiveBeginsWith [ - self filter: MDLBeginsWithFilter -] - -{ #category : #accessing } -MDLNestedList >> filterSubstring [ - self filter: MDLSubstringFilter -] - -{ #category : #accessing } -MDLNestedList >> filteredElements [ - ^ self displayResearchFilter ifNil: [ self elements ] ifNotNil: [ filteredElements ] -] - -{ #category : #accessing } -MDLNestedList >> format [ - ^ self strategy format ifNil: [ #asString ] -] - -{ #category : #accessing } -MDLNestedList >> format: anObject [ - self strategy format: anObject -] - -{ #category : #testing } -MDLNestedList >> hasDraggableItems [ - ^ self dragAndDropBlock notNil -] - -{ #category : #accessing } -MDLNestedList >> helpBlock [ - ^ self strategy helpBlock -] - -{ #category : #accessing } -MDLNestedList >> helpBlock: anObject [ - self strategy helpBlock: anObject -] - -{ #category : #accessing } -MDLNestedList >> iconBlock [ - ^ self strategy iconBlock -] - -{ #category : #accessing } -MDLNestedList >> iconBlock: anObject [ - self strategy iconBlock: anObject -] - -{ #category : #private } -MDLNestedList >> idFor: aSymbol [ - ^ aSymbol, self id -] - -{ #category : #accessing } -MDLNestedList >> indexOfRootElementContainingSelectedEntity [ - self selectedEntity ifNil: [ ^ 0 ]. - ^ self filteredElements - indexOf: self selectedEntity - ifAbsent: [ self filteredElements - detect: [ :element | self isIncludingSelectedChildren: element ] - ifFound: [ :element | self filteredElements indexOf: element ] - ifNone: [ "The selected element is not at all in the tree" 1 ] ] -] - -{ #category : #initialization } -MDLNestedList >> initialize [ - super initialize. - self - listMaxSize: 150; - displayResearchField: false; - isJsAction: false; - listStyle: #standard; - filterInsensitiveBeginsWith; - onLoadHook: 'componentHandler.upgradeDom();' -] - -{ #category : #positionning } -MDLNestedList >> isIncludingSelectedChildren: anElement [ - ^ (self childrenBlock value: anElement) anySatisfy: [ :aChildren | aChildren = selectedEntity or: [ self isIncludingSelectedChildren: aChildren ] ] -] - -{ #category : #accessing } -MDLNestedList >> isJsAction [ - ^ self strategy isJsAction -] - -{ #category : #accessing } -MDLNestedList >> isJsAction: anObject [ - self strategy isJsAction: anObject -] - -{ #category : #javascript } -MDLNestedList >> jsOnLoadHook [ - ^ self onLoadHook js -] - -{ #category : #accessing } -MDLNestedList >> listElementsDynamicalLoadingStep [ - "It is the number of elements asked in ajax to the server when user scroll" - ^ self listMaxSize / 5 -] - -{ #category : #accessing } -MDLNestedList >> listMaxSize [ - ^ listMaxSize -] - -{ #category : #accessing } -MDLNestedList >> listMaxSize: anObject [ - listMaxSize := anObject -] - -{ #category : #accessing } -MDLNestedList >> listStyle [ - ^ listStyle -] - -{ #category : #accessing } -MDLNestedList >> listStyle: anObject [ - listStyle := anObject -] - -{ #category : #private } -MDLNestedList >> obtainElementForPath: aPath [ - | path | - path := $: split: aPath. - ^ (path allButLast - inject: self filteredElements - into: [ :elemts :anIndex | - | res | - res := self childrenBlock value: (elemts at: anIndex asNumber). - self childrenSortBlock ifNil: [ res ] ifNotNil: [ :sortBlock | res sorted: sortBlock ] ]) at: path last asNumber -] - -{ #category : #private } -MDLNestedList >> obtainTreeFor: anElement [ - ^ obtainedTreesCache at: anElement ifAbsentPut: [ MDLNestedListTreeNode list: self element: anElement ] -] - -{ #category : #accessing } -MDLNestedList >> onClickJs: anActionBlock [ - self actionBlock: anActionBlock. - self isJsAction: true -] - -{ #category : #accessing } -MDLNestedList >> onLoadHook [ - ^ onLoadHook -] - -{ #category : #accessing } -MDLNestedList >> onLoadHook: anObject [ - onLoadHook := anObject -] - -{ #category : #rendering } -MDLNestedList >> printHtmlForElementsFrom: start to: end context: aContext on: stream [ - self - printResultOf: [ :html | - (start <= self filteredElements size and: [ end >= 1 ]) - ifTrue: [ - self filteredElements - from: (start max: 1) - to: (end min: self filteredElements size) - do: [ :anElement | - self - renderListTree: (self obtainTreeFor: anElement) - index: (self filteredElements indexOf: anElement) - indentedBy: 1 - on: html ] ] ] - context: aContext - on: stream -] - -{ #category : #rendering } -MDLNestedList >> printResultOf: aBlock context: aContext on: stream [ - | document | - document := (WAHtmlDocument on: stream codec: GRNullCodec new) - scriptGenerator: WADefaultScriptGenerator new; - yourself. - aContext document: document. - (WAHtmlCanvas context: aContext) - render: aBlock; - flush. - document scriptGenerator closeOn: document -] - -{ #category : #rendering } -MDLNestedList >> printSublistFor: anIntervalRequest context: aContext on: stream [ - self - printResultOf: [ :html | - self - renderSublistOf: (self obtainTreeFor: (self obtainElementForPath: anIntervalRequest)) children - parentIndex: anIntervalRequest - indentedBy: (anIntervalRequest occurrencesOf: $:) + 1 - on: html ] - context: aContext - on: stream -] - -{ #category : #rendering } -MDLNestedList >> renderContentOn: html [ - self ensureId: html. - obtainedTreesCache := IdentityDictionary new. "Reset cache while loading page." - html div - id: (self idFor: #nestedList); - class: #nestedList; - class: self listStyle; - with: [ - self renderFilterFieldOn: html. - html div - id: (self idFor: #listContent); - class: #listContent; - class: #withSearch if: self displayResearchField; - with: [ self renderListOn: html ] ] -] - -{ #category : #researchField } -MDLNestedList >> renderFilterFieldOn: html [ - self displayResearchField ifFalse: [ ^ self ]. - - html div - class: #listResearchField; - with: [ html - mdlTextFieldContainer: [ html mdlTextFieldLabel - for: (self idFor: #researchFieldId); - with: 'Search'. - html mdlTextFieldInput - id: (self idFor: #researchFieldId); - type: 'text'; - value: self displayResearchFilter; - onChange: - (html jQuery ajax - callback: [ :filt | self displayResearchFilter: filt ] value: 'event.target.value' js; - onComplete: - ((html jQuery: '#' , (self idFor: #listContainer)) parent load - html: [ :htm | self renderListOn: htm ]; - onComplete: (self jsOnLoadHook , ('scrollToSelection();defineExpandable();stopSpinnerOf("' , (self idFor: #researchFieldId) , '")') js))) ]. - html mdlSpinner singleColor ] -] - -{ #category : #rendering } -MDLNestedList >> renderHelpOf: anItem at: anId on: html [ - | helpText | - (self helpBlock isNil - or: [ self helpBlock argumentCount = 1 and: [ (helpText := self helpBlock value: anItem) isEmptyOrNil ] ]) - ifTrue: [ ^ self ]. - - html mdlTooltip - large; - for: anId; - with: - (self helpBlock argumentCount = 1 - ifTrue: [ helpText ] - ifFalse: [ self helpBlock mdlCull: anItem cull: html ]) -] - -{ #category : #rendering } -MDLNestedList >> renderListOn: html [ - | div | - div := html div - id: (self idFor: #listContainer); - class: #listContainer. - self setDataForCallBackFor: div html: html. - div - with: [ - | elementsToDisplay firstElementIndex | - elementsToDisplay := self elementsDisplayList. - firstElementIndex := self filteredElements - indexOf: (elementsToDisplay ifEmpty: [ nil ] ifNotEmpty: [ :coll | coll first ]). - html unorderedList - id: (self idFor: #expList); - class: #expList; - with: [ - elementsToDisplay - doWithIndex: [ :item :index | - self strategy - renderListTree: (self obtainTreeFor: item) - index: index + firstElementIndex - 1 - indentedBy: 1 - on: html ] ] ]. - self draggableMechanism: html forDiv: div -] - -{ #category : #accessing } -MDLNestedList >> rightIconBlock [ - ^ self strategy rightIconBlock -] - -{ #category : #accessing } -MDLNestedList >> rightIconBlock: anObject [ - self strategy rightIconBlock: anObject -] - -{ #category : #accessing } -MDLNestedList >> selectedEntity [ - ^ selectedEntity -] - -{ #category : #accessing } -MDLNestedList >> selectedEntity: anObject [ - selectedEntity := anObject -] - -{ #category : #hooks } -MDLNestedList >> setAjaxStrategy [ - self strategy: self strategy asAjaxStrategy -] - -{ #category : #javascript } -MDLNestedList >> setDataForCallBackFor: div html: html [ - div - attributeAt: #'data-url' put: html actionUrl asString; - attributeAt: #'data-cbId' put: (self defineScrollCallbackOn: div) asString; - attributeAt: #'data-childrenCbId' put: (self defineChildrenCallbackOn: div) asString; - attributeAt: #'data-listMaxSize' put: self listMaxSize asString; - attributeAt: #'data-lastIndexAsked' put: (self filteredElements indexOf: self selectedEntity ifAbsent: 1) asString; - attributeAt: #'data-onLoadHook' put: self jsOnLoadHook; - attributeAt: #'data-loadingstep' put: self listElementsDynamicalLoadingStep asString -] - -{ #category : #hooks } -MDLNestedList >> states [ - self flag: #BECAREFUL. "I am absolutly not sure we want to do this. I let it to try but it might be removed." - ^ Array with: self -] - -{ #category : #accessing } -MDLNestedList >> strategy [ - ^ strategy - ifNil: [ strategy := MDLNestedListItemRenderAnchorStrategy new ] -] - -{ #category : #accessing } -MDLNestedList >> strategy: anObject [ - strategy := anObject -] - -{ #category : #researchField } -MDLNestedList >> withResearchField [ - self displayResearchField: true -] +" +I am a component use to display nicely a list of elements. +I am also able to display nested list as a tree. + +Description +------------------ + +I display a list of elements and I manage most of the css needed to make a good rendering. +For the icon check MDLListIconComponent or give any component you want. + +For more info you can test the demo. + +Public API and Key Messages +------------------ + +- #actionBlock: aBlock Allow to set an action to execute on click +- #elements: aCollection Is the list of elements to display +- #children: aBlock Return for each element his childrens +- #format: aBlock Is a block that take an element and return the element with the right format +- #selectedEntity: anElement If the element in parameter is in the list, it zill be highlighted +- #helpBlock: aBlock Allow to add a fly by help on elements +- #iconBlock: aBlock Allow to add an icon on each line + +Example +------------------ + + (SYNListComponent elements: #(1 34 56 89) children: [ :number | number even ifTrue: [ {(number + 1) . (number + 3) } ] ifFalse: [ #() ] ] ]) + actionBlock: [ :elem | Transcript crShow: elem asString ]; + format: [ :elem | elem asString , '%' ]; + selectedEntity: 34; + yourself + +Internal Representation and Key Implementation Points. +------------------ + + Instance Variables + actionBlock: A block executed when an element is selected + children: A block that return the list of children of an element + elements: A collection of elements to display + format: A block executed to format an element + selectedEntity: An element that need to be highlighted in the list + helpBlock: A block that return an optional fly-by-felp for an element + iconBlock: A block thet return an optional SYNListIconComponent for a line of the list +" +Class { + #name : #MDLNestedList, + #superclass : #MDLWidget, + #instVars : [ + 'elements', + 'entryCustomizationHook', + 'filteredElements', + 'selectedEntity', + 'dragAndDropBlock', + 'displayResearchField', + 'displayResearchFilter', + 'filter', + 'listStyle', + 'onLoadHook', + 'listMaxSize', + 'obtainedTreesCache', + 'strategy' + ], + #category : #'Material-Design-Lite-Widgets-List' +} + +{ #category : #'instance creation' } +MDLNestedList class >> elements: aCollection [ + ^ self new + elements: aCollection; + yourself +] + +{ #category : #'instance creation' } +MDLNestedList class >> elements: aCollection children: aBlockOrSymbole [ + ^ (self elements: aCollection) + childrenBlock: aBlockOrSymbole; + yourself +] + +{ #category : #accessing } +MDLNestedList >> actionBlock [ + ^ self strategy actionBlock +] + +{ #category : #accessing } +MDLNestedList >> actionBlock: aBlock [ + self + assert: aBlock argumentCount = 1 + description: + 'This block must take one argument; it will be the clicked entity in the list'. + self strategy actionBlock: aBlock +] + +{ #category : #private } +MDLNestedList >> at: anInteger ifPresent: aBlockClosure [ + aBlockClosure value: (self filteredElements at: anInteger) +] + +{ #category : #accessing } +MDLNestedList >> beCompact [ + self listStyle: #compact +] + +{ #category : #accessing } +MDLNestedList >> beStandard [ + self listStyle: #standard +] + +{ #category : #accessing } +MDLNestedList >> children: aBlockOrSymbol [ + self childrenBlock: aBlockOrSymbol +] + +{ #category : #accessing } +MDLNestedList >> childrenBlock [ + ^ self strategy childrenBlock + ifNil: [ self strategy childrenBlock: [ :item | #() ]. + self strategy childrenBlock ] +] + +{ #category : #accessing } +MDLNestedList >> childrenBlock: anObject [ + self strategy childrenBlock: anObject +] + +{ #category : #accessing } +MDLNestedList >> childrenSortBlock [ + ^ self strategy childrenSortBlock +] + +{ #category : #accessing } +MDLNestedList >> childrenSortBlock: aBlock [ + self strategy childrenSortBlock: aBlock +] + +{ #category : #javascript } +MDLNestedList >> defineChildrenCallbackOn: aDiv [ + ^ aDiv + storeCallback: + (WAValueCallback + on: [ :intervalRequest | + self requestContext + respond: [ :response | + self + printSublistFor: intervalRequest + context: aDiv canvas context + on: + (response + doNotCache; + contentType: WAMimeType textHtml; + stream) ] ]) +] + +{ #category : #javascript } +MDLNestedList >> defineScrollCallbackOn: aDiv [ + ^ aDiv + storeCallback: + (WAValueCallback + on: [ :intervalRequest | + | interval | + interval := $: split: intervalRequest. + self requestContext + respond: [ :response | + self + printHtmlForElementsFrom: interval first asNumber + to: interval last asNumber + context: aDiv canvas context + on: + (response + doNotCache; + contentType: WAMimeType textHtml; + stream) ] ]) +] + +{ #category : #accessing } +MDLNestedList >> displayResearchField [ + ^ displayResearchField +] + +{ #category : #accessing } +MDLNestedList >> displayResearchField: aBoolean [ + displayResearchField := aBoolean +] + +{ #category : #accessing } +MDLNestedList >> displayResearchFilter [ + ^ displayResearchFilter +] + +{ #category : #accessing } +MDLNestedList >> displayResearchFilter: aFilter [ + aFilter + ifEmpty: [ + displayResearchFilter := nil. + filteredElements := #() ] + ifNotEmpty: [ + displayResearchFilter := aFilter. + filteredElements := self filter + selectMatchingFrom: self elements + format: self format + with: self displayResearchFilter ] +] + +{ #category : #accessing } +MDLNestedList >> dragAndDropBlock [ + ^ dragAndDropBlock +] + +{ #category : #accessing } +MDLNestedList >> dragAndDropBlock: anObject [ + dragAndDropBlock := anObject +] + +{ #category : #draggable } +MDLNestedList >> draggableMechanism: html forDiv: div [ + self hasDraggableItems + ifTrue: [ + html + script: + (self + draggableScript: html actionUrl + cb: + (div + storeCallback: + (WAValueCallback + on: [ :drag | + | dragValues | + dragValues := drag substrings: ';'. + self dragAndDropBlock + value: (self obtainElementForPath: dragValues first) + value: (self obtainElementForPath: dragValues second) ]))) ] +] + +{ #category : #draggable } +MDLNestedList >> draggableScript:url cb: draggableCb [ + ^ 'function dragListItem(ev, index) { + ev.dataTransfer.setData("sourceIndex", index); +} + + +function dropListItem(ev, index){ + var source = ev.dataTransfer.getData("sourceIndex"); + var target = index; + if(source == target) console.log("Sleep"); + else post("' , url asString , '",{' , draggableCb + , + ': source + ";" + target});; +}' +] + +{ #category : #accessing } +MDLNestedList >> elements [ + ^ elements value +] + +{ #category : #accessing } +MDLNestedList >> elements: anObject [ + elements := anObject. + "reinitialize the filter when list change" + self displayResearchFilter: '' +] + +{ #category : #accessing } +MDLNestedList >> elementsDisplayList [ + | start overflow | + ^ self filteredElements size <= self listMaxSize + ifTrue: [ self filteredElements ] + ifFalse: [ start := self indexOfRootElementContainingSelectedEntity - (self listMaxSize / 2) max: 1. + overflow := 0 max: start + self listMaxSize - self filteredElements size. + self filteredElements copyFrom: start - overflow to: start + self listMaxSize - 1 - overflow ] +] + +{ #category : #accessing } +MDLNestedList >> entryCustomizationHook [ + ^ entryCustomizationHook +] + +{ #category : #accessing } +MDLNestedList >> entryCustomizationHook: anObject [ + entryCustomizationHook := anObject +] + +{ #category : #accessing } +MDLNestedList >> filter [ + ^ filter +] + +{ #category : #accessing } +MDLNestedList >> filter: anObject [ + filter := anObject +] + +{ #category : #accessing } +MDLNestedList >> filterInsensitiveBeginsWith [ + self filter: MDLInsensitiveBeginsWithFilter +] + +{ #category : #accessing } +MDLNestedList >> filterInsensitiveSubstring [ + self filter: MDLInsensitiveSubstringFilter +] + +{ #category : #accessing } +MDLNestedList >> filterPseudoRegex [ + self filter: MDLPseudoRegexFilter +] + +{ #category : #accessing } +MDLNestedList >> filterSensitiveBeginsWith [ + self filter: MDLBeginsWithFilter +] + +{ #category : #accessing } +MDLNestedList >> filterSubstring [ + self filter: MDLSubstringFilter +] + +{ #category : #accessing } +MDLNestedList >> filteredElements [ + ^ self displayResearchFilter ifNil: [ self elements ] ifNotNil: [ filteredElements ] +] + +{ #category : #accessing } +MDLNestedList >> format [ + ^ self strategy format ifNil: [ #asString ] +] + +{ #category : #accessing } +MDLNestedList >> format: anObject [ + self strategy format: anObject +] + +{ #category : #testing } +MDLNestedList >> hasDraggableItems [ + ^ self dragAndDropBlock notNil +] + +{ #category : #accessing } +MDLNestedList >> helpBlock [ + ^ self strategy helpBlock +] + +{ #category : #accessing } +MDLNestedList >> helpBlock: anObject [ + self strategy helpBlock: anObject +] + +{ #category : #accessing } +MDLNestedList >> iconBlock [ + ^ self strategy iconBlock +] + +{ #category : #accessing } +MDLNestedList >> iconBlock: anObject [ + self strategy iconBlock: anObject +] + +{ #category : #private } +MDLNestedList >> idFor: aSymbol [ + ^ aSymbol, self id +] + +{ #category : #accessing } +MDLNestedList >> indexOfRootElementContainingSelectedEntity [ + self selectedEntity ifNil: [ ^ 0 ]. + ^ self filteredElements + indexOf: self selectedEntity + ifAbsent: [ self filteredElements + detect: [ :element | self isIncludingSelectedChildren: element ] + ifFound: [ :element | self filteredElements indexOf: element ] + ifNone: [ "The selected element is not at all in the tree" 1 ] ] +] + +{ #category : #initialization } +MDLNestedList >> initialize [ + super initialize. + self + listMaxSize: 150; + displayResearchField: false; + isJsAction: false; + listStyle: #standard; + filterInsensitiveBeginsWith; + onLoadHook: 'componentHandler.upgradeDom();' +] + +{ #category : #positionning } +MDLNestedList >> isIncludingSelectedChildren: anElement [ + ^ (self childrenBlock value: anElement) anySatisfy: [ :aChildren | aChildren = selectedEntity or: [ self isIncludingSelectedChildren: aChildren ] ] +] + +{ #category : #accessing } +MDLNestedList >> isJsAction [ + ^ self strategy isJsAction +] + +{ #category : #accessing } +MDLNestedList >> isJsAction: anObject [ + self strategy isJsAction: anObject +] + +{ #category : #javascript } +MDLNestedList >> jsOnLoadHook [ + ^ self onLoadHook js +] + +{ #category : #accessing } +MDLNestedList >> listElementsDynamicalLoadingStep [ + "It is the number of elements asked in ajax to the server when user scroll" + ^ self listMaxSize / 5 +] + +{ #category : #accessing } +MDLNestedList >> listMaxSize [ + ^ listMaxSize +] + +{ #category : #accessing } +MDLNestedList >> listMaxSize: anObject [ + listMaxSize := anObject +] + +{ #category : #accessing } +MDLNestedList >> listStyle [ + ^ listStyle +] + +{ #category : #accessing } +MDLNestedList >> listStyle: anObject [ + listStyle := anObject +] + +{ #category : #private } +MDLNestedList >> obtainElementForPath: aPath [ + | path | + path := $: split: aPath. + ^ (path allButLast + inject: self filteredElements + into: [ :elemts :anIndex | + | res | + res := self childrenBlock value: (elemts at: anIndex asNumber). + self childrenSortBlock ifNil: [ res ] ifNotNil: [ :sortBlock | res sorted: sortBlock ] ]) at: path last asNumber +] + +{ #category : #private } +MDLNestedList >> obtainTreeFor: anElement [ + ^ obtainedTreesCache at: anElement ifAbsentPut: [ MDLNestedListTreeNode list: self element: anElement ] +] + +{ #category : #accessing } +MDLNestedList >> onClickJs: anActionBlock [ + self actionBlock: anActionBlock. + self isJsAction: true +] + +{ #category : #accessing } +MDLNestedList >> onLoadHook [ + ^ onLoadHook +] + +{ #category : #accessing } +MDLNestedList >> onLoadHook: anObject [ + onLoadHook := anObject +] + +{ #category : #rendering } +MDLNestedList >> printHtmlForElementsFrom: start to: end context: aContext on: stream [ + self + printResultOf: [ :html | + (start <= self filteredElements size and: [ end >= 1 ]) + ifTrue: [ + self filteredElements + from: (start max: 1) + to: (end min: self filteredElements size) + do: [ :anElement | + self + renderListTree: (self obtainTreeFor: anElement) + index: (self filteredElements indexOf: anElement) + indentedBy: 1 + on: html ] ] ] + context: aContext + on: stream +] + +{ #category : #rendering } +MDLNestedList >> printResultOf: aBlock context: aContext on: stream [ + | document | + document := (WAHtmlDocument on: stream codec: GRNullCodec new) + scriptGenerator: WADefaultScriptGenerator new; + yourself. + aContext document: document. + (WAHtmlCanvas context: aContext) + render: aBlock; + flush. + document scriptGenerator closeOn: document +] + +{ #category : #rendering } +MDLNestedList >> printSublistFor: anIntervalRequest context: aContext on: stream [ + self + printResultOf: [ :html | + self + renderSublistOf: (self obtainTreeFor: (self obtainElementForPath: anIntervalRequest)) children + parentIndex: anIntervalRequest + indentedBy: (anIntervalRequest occurrencesOf: $:) + 1 + on: html ] + context: aContext + on: stream +] + +{ #category : #rendering } +MDLNestedList >> renderContentOn: html [ + self ensureId: html. + obtainedTreesCache := IdentityDictionary new. "Reset cache while loading page." + html div + id: (self idFor: #nestedList); + class: #nestedList; + class: self listStyle; + with: [ + self renderFilterFieldOn: html. + html div + id: (self idFor: #listContent); + class: #listContent; + class: #withSearch if: self displayResearchField; + with: [ self renderListOn: html ] ] +] + +{ #category : #researchField } +MDLNestedList >> renderFilterFieldOn: html [ + self displayResearchField ifFalse: [ ^ self ]. + + html div + class: #listResearchField; + with: [ html + mdlTextFieldContainer: [ html mdlTextFieldLabel + for: (self idFor: #researchFieldId); + with: 'Search'. + html mdlTextFieldInput + id: (self idFor: #researchFieldId); + type: 'text'; + value: self displayResearchFilter; + onChange: + (html jQuery ajax + callback: [ :filt | self displayResearchFilter: filt ] value: 'event.target.value' js; + onComplete: + ((html jQuery: '#' , (self idFor: #listContainer)) parent load + html: [ :htm | self renderListOn: htm ]; + onComplete: (self jsOnLoadHook , ('scrollToSelection();defineExpandable();stopSpinnerOf("' , (self idFor: #researchFieldId) , '")') js))) ]. + html mdlSpinner singleColor ] +] + +{ #category : #rendering } +MDLNestedList >> renderHelpOf: anItem at: anId on: html [ + | helpText | + (self helpBlock isNil + or: [ self helpBlock argumentCount = 1 and: [ (helpText := self helpBlock value: anItem) isEmptyOrNil ] ]) + ifTrue: [ ^ self ]. + + html mdlTooltip + large; + for: anId; + with: + (self helpBlock argumentCount = 1 + ifTrue: [ helpText ] + ifFalse: [ self helpBlock mdlCull: anItem cull: html ]) +] + +{ #category : #rendering } +MDLNestedList >> renderListOn: html [ + | div | + div := html div + id: (self idFor: #listContainer); + class: #listContainer. + self setDataForCallBackFor: div html: html. + div + with: [ + | elementsToDisplay firstElementIndex | + elementsToDisplay := self elementsDisplayList. + firstElementIndex := self filteredElements + indexOf: (elementsToDisplay ifEmpty: [ nil ] ifNotEmpty: [ :coll | coll first ]). + html unorderedList + id: (self idFor: #expList); + class: #expList; + with: [ + elementsToDisplay + doWithIndex: [ :item :index | + self strategy + renderListTree: (self obtainTreeFor: item) + index: index + firstElementIndex - 1 + indentedBy: 1 + on: html ] ] ]. + self draggableMechanism: html forDiv: div +] + +{ #category : #accessing } +MDLNestedList >> rightIconBlock [ + ^ self strategy rightIconBlock +] + +{ #category : #accessing } +MDLNestedList >> rightIconBlock: anObject [ + self strategy rightIconBlock: anObject +] + +{ #category : #accessing } +MDLNestedList >> selectedEntity [ + ^ selectedEntity +] + +{ #category : #accessing } +MDLNestedList >> selectedEntity: anObject [ + selectedEntity := anObject +] + +{ #category : #hooks } +MDLNestedList >> setAjaxStrategy [ + self strategy: self strategy asAjaxStrategy +] + +{ #category : #javascript } +MDLNestedList >> setDataForCallBackFor: div html: html [ + div + attributeAt: #'data-url' put: html actionUrl asString; + attributeAt: #'data-cbId' put: (self defineScrollCallbackOn: div) asString; + attributeAt: #'data-childrenCbId' put: (self defineChildrenCallbackOn: div) asString; + attributeAt: #'data-listMaxSize' put: self listMaxSize asString; + attributeAt: #'data-lastIndexAsked' put: (self filteredElements indexOf: self selectedEntity ifAbsent: 1) asString; + attributeAt: #'data-onLoadHook' put: self jsOnLoadHook; + attributeAt: #'data-loadingstep' put: self listElementsDynamicalLoadingStep asString +] + +{ #category : #hooks } +MDLNestedList >> states [ + self flag: #BECAREFUL. "I am absolutly not sure we want to do this. I let it to try but it might be removed." + ^ Array with: self +] + +{ #category : #accessing } +MDLNestedList >> strategy [ + ^ strategy + ifNil: [ strategy := MDLNestedListItemRenderAnchorStrategy new ] +] + +{ #category : #accessing } +MDLNestedList >> strategy: anObject [ + strategy := anObject +] + +{ #category : #researchField } +MDLNestedList >> withResearchField [ + self displayResearchField: true +] diff --git a/src/Material-Design-Lite-Widgets/MDLNestedListItemRenderAbstractStrategy.class.st b/src/Material-Design-Lite-Widgets/MDLNestedListItemRenderAbstractStrategy.class.st index 7d7fb49b..e5dcf5a9 100644 --- a/src/Material-Design-Lite-Widgets/MDLNestedListItemRenderAbstractStrategy.class.st +++ b/src/Material-Design-Lite-Widgets/MDLNestedListItemRenderAbstractStrategy.class.st @@ -1,221 +1,221 @@ -Class { - #name : #MDLNestedListItemRenderAbstractStrategy, - #superclass : #MDLWidget, - #instVars : [ - 'isJsAction', - 'actionBlock', - 'helpBlock', - 'childrenBlock', - 'childrenSortBlock', - 'entryCustomizationHook', - 'format', - 'iconBlock', - 'rightIconBlock' - ], - #category : #'Material-Design-Lite-Widgets-List' -} - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> actionBlock [ - ^ actionBlock -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> actionBlock: anObject [ - actionBlock := anObject -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> childrenBlock [ - ^ childrenBlock -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> childrenBlock: anObject [ - childrenBlock := anObject -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> childrenSortBlock [ - ^ childrenSortBlock -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> childrenSortBlock: anObject [ - childrenSortBlock := anObject -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> entryCustomizationHook [ - ^ entryCustomizationHook -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> entryCustomizationHook: anObject [ - entryCustomizationHook := anObject -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> format [ - ^ format -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> format: anObject [ - format := anObject -] - -{ #category : #testing } -MDLNestedListItemRenderAbstractStrategy >> hasCustomizationForEntry [ - ^ self entryCustomizationHook notNil -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> helpBlock [ - ^ helpBlock -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> helpBlock: anObject [ - helpBlock := anObject -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> iconBlock [ - ^ iconBlock -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> iconBlock: anObject [ - iconBlock := anObject -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> isJsAction [ - ^ isJsAction -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> isJsAction: anObject [ - isJsAction := anObject -] - -{ #category : #rendering } -MDLNestedListItemRenderAbstractStrategy >> renderHelpOf: anItem at: anId on: html [ - | helpText | - (self helpBlock isNil - or: [ self helpBlock argumentCount = 1 and: [ (helpText := self helpBlock value: anItem) isEmptyOrNil ] ]) - ifTrue: [ ^ self ]. - - html mdlTooltip - large; - for: anId; - with: - (self helpBlock argumentCount = 1 - ifTrue: [ helpText ] - ifFalse: [ self helpBlock mdlCull: anItem cull: html ]) -] - -{ #category : #rendering } -MDLNestedListItemRenderAbstractStrategy >> renderIcon: aBlock Of: anItem on: html [ - aBlock ifNil: [ ^ self ]. - - self - assert: (aBlock argumentCount between: 1 and: 2) - description: - 'The icon block should have 1 or 2 arguments only. The first argument should be the item to display. If this is the only parameter the block should return a WAComponent to render. The second optional parameter will be an html canvas if you want to render directly something without passing by a component.'. - - aBlock argumentCount = 1 - ifTrue: [ html render: (aBlock value: anItem) ] - ifFalse: [ aBlock value: anItem value: html ] -] - -{ #category : #rendering } -MDLNestedListItemRenderAbstractStrategy >> renderItem: aNode index: anIndex inDiv: div indentedBy: anInteger on: html [ - | htmlElement | - htmlElement := self getHtmlElementForNode: aNode inDiv: div index: anIndex indentedBy: anInteger on: html. - htmlElement - with: [ html span - class: #item; - id: html nextId; - with: ((self format value: aNode element) ifEmpty: [ $  ]). - self renderHelpOf: aNode element at: html lastId on: html ]. - aNode children - ifNotEmpty: [ html div - onClick: 'expandCollapse(this)'; - class: #icon ] -] - -{ #category : #rendering } -MDLNestedListItemRenderAbstractStrategy >> renderItemContentOf: aNode index: anIndex indentedBy: anInteger on: html [ - | div | - div := html div class: #itemContener. - self hasCustomizationForEntry - ifTrue: [ self entryCustomizationHook mdlCull: div cull: aNode element ]. - div - attributeAt: 'draggable' put: 'true'; - attributeAt: 'onDragOver' - put: 'if("' , anIndex asString , '" != event.dataTransfer.getData("sourceIndex")) {event.preventDefault();}'; - attributeAt: 'ondrop' put: 'dropListItem(event, "' , anIndex asString , '");'; - attributeAt: 'ondragstart' put: 'dragListItem(event,"' , anIndex asString , '")'; - style: 'padding-left: ' , (15 * anInteger) asString , 'px;'; - class: #isSelected if: aNode selectedElement; - with: [ - self renderIcon: self iconBlock Of: aNode element on: html. - self - renderItem: aNode - index: anIndex - inDiv: div - indentedBy: anInteger - on: html. - self renderIcon: self rightIconBlock Of: aNode element on: html ] -] - -{ #category : #rendering } -MDLNestedListItemRenderAbstractStrategy >> renderListTree: aTree index: index indentedBy: indentation on: html [ - html listItem - class: #expanded if: aTree selectedBranch; - class: #collapsed if: aTree selectedBranch not; - class: #hasChildren if: aTree children isNotEmpty; - attributeAt: #index put: index; - with: [ - self - renderItemContentOf: aTree - index: index - indentedBy: indentation - on: html. - aTree selectedBranch - ifTrue: [ - self - renderSublistOf: aTree children - parentIndex: index - indentedBy: indentation - on: html ] ] -] - -{ #category : #rendering } -MDLNestedListItemRenderAbstractStrategy >> renderSublistOf: children parentIndex: parentIndex indentedBy: anInteger on: html [ - | sortedChildren | - children ifEmpty: [ ^ self ]. - - sortedChildren := self childrenSortBlock ifNil: [ children ] ifNotNil: [ :sortBlock | children sorted: [ :node1 :node2 | sortBlock value: node1 element value: node2 element ] ]. - html - unorderedList: [ - sortedChildren - doWithIndex: [ :child :index | - self - renderListTree: child - index: parentIndex asString, ':', index asString - indentedBy: anInteger + 1 - on: html ] ] -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> rightIconBlock [ - ^ rightIconBlock -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> rightIconBlock: anObject [ - rightIconBlock := anObject -] +Class { + #name : #MDLNestedListItemRenderAbstractStrategy, + #superclass : #MDLWidget, + #instVars : [ + 'isJsAction', + 'actionBlock', + 'helpBlock', + 'childrenBlock', + 'childrenSortBlock', + 'entryCustomizationHook', + 'format', + 'iconBlock', + 'rightIconBlock' + ], + #category : #'Material-Design-Lite-Widgets-List' +} + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> actionBlock [ + ^ actionBlock +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> actionBlock: anObject [ + actionBlock := anObject +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> childrenBlock [ + ^ childrenBlock +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> childrenBlock: anObject [ + childrenBlock := anObject +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> childrenSortBlock [ + ^ childrenSortBlock +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> childrenSortBlock: anObject [ + childrenSortBlock := anObject +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> entryCustomizationHook [ + ^ entryCustomizationHook +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> entryCustomizationHook: anObject [ + entryCustomizationHook := anObject +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> format [ + ^ format +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> format: anObject [ + format := anObject +] + +{ #category : #testing } +MDLNestedListItemRenderAbstractStrategy >> hasCustomizationForEntry [ + ^ self entryCustomizationHook notNil +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> helpBlock [ + ^ helpBlock +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> helpBlock: anObject [ + helpBlock := anObject +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> iconBlock [ + ^ iconBlock +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> iconBlock: anObject [ + iconBlock := anObject +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> isJsAction [ + ^ isJsAction +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> isJsAction: anObject [ + isJsAction := anObject +] + +{ #category : #rendering } +MDLNestedListItemRenderAbstractStrategy >> renderHelpOf: anItem at: anId on: html [ + | helpText | + (self helpBlock isNil + or: [ self helpBlock argumentCount = 1 and: [ (helpText := self helpBlock value: anItem) isEmptyOrNil ] ]) + ifTrue: [ ^ self ]. + + html mdlTooltip + large; + for: anId; + with: + (self helpBlock argumentCount = 1 + ifTrue: [ helpText ] + ifFalse: [ self helpBlock mdlCull: anItem cull: html ]) +] + +{ #category : #rendering } +MDLNestedListItemRenderAbstractStrategy >> renderIcon: aBlock Of: anItem on: html [ + aBlock ifNil: [ ^ self ]. + + self + assert: (aBlock argumentCount between: 1 and: 2) + description: + 'The icon block should have 1 or 2 arguments only. The first argument should be the item to display. If this is the only parameter the block should return a WAComponent to render. The second optional parameter will be an html canvas if you want to render directly something without passing by a component.'. + + aBlock argumentCount = 1 + ifTrue: [ html render: (aBlock value: anItem) ] + ifFalse: [ aBlock value: anItem value: html ] +] + +{ #category : #rendering } +MDLNestedListItemRenderAbstractStrategy >> renderItem: aNode index: anIndex inDiv: div indentedBy: anInteger on: html [ + | htmlElement | + htmlElement := self getHtmlElementForNode: aNode inDiv: div index: anIndex indentedBy: anInteger on: html. + htmlElement + with: [ html span + class: #item; + id: html nextId; + with: ((self format value: aNode element) ifEmpty: [ $  ]). + self renderHelpOf: aNode element at: html lastId on: html ]. + aNode children + ifNotEmpty: [ html div + onClick: 'expandCollapse(this)'; + class: #icon ] +] + +{ #category : #rendering } +MDLNestedListItemRenderAbstractStrategy >> renderItemContentOf: aNode index: anIndex indentedBy: anInteger on: html [ + | div | + div := html div class: #itemContener. + self hasCustomizationForEntry + ifTrue: [ self entryCustomizationHook mdlCull: div cull: aNode element ]. + div + attributeAt: 'draggable' put: 'true'; + attributeAt: 'onDragOver' + put: 'if("' , anIndex asString , '" != event.dataTransfer.getData("sourceIndex")) {event.preventDefault();}'; + attributeAt: 'ondrop' put: 'dropListItem(event, "' , anIndex asString , '");'; + attributeAt: 'ondragstart' put: 'dragListItem(event,"' , anIndex asString , '")'; + style: 'padding-left: ' , (15 * anInteger) asString , 'px;'; + class: #isSelected if: aNode selectedElement; + with: [ + self renderIcon: self iconBlock Of: aNode element on: html. + self + renderItem: aNode + index: anIndex + inDiv: div + indentedBy: anInteger + on: html. + self renderIcon: self rightIconBlock Of: aNode element on: html ] +] + +{ #category : #rendering } +MDLNestedListItemRenderAbstractStrategy >> renderListTree: aTree index: index indentedBy: indentation on: html [ + html listItem + class: #expanded if: aTree selectedBranch; + class: #collapsed if: aTree selectedBranch not; + class: #hasChildren if: aTree children isNotEmpty; + attributeAt: #index put: index; + with: [ + self + renderItemContentOf: aTree + index: index + indentedBy: indentation + on: html. + aTree selectedBranch + ifTrue: [ + self + renderSublistOf: aTree children + parentIndex: index + indentedBy: indentation + on: html ] ] +] + +{ #category : #rendering } +MDLNestedListItemRenderAbstractStrategy >> renderSublistOf: children parentIndex: parentIndex indentedBy: anInteger on: html [ + | sortedChildren | + children ifEmpty: [ ^ self ]. + + sortedChildren := self childrenSortBlock ifNil: [ children ] ifNotNil: [ :sortBlock | children sorted: [ :node1 :node2 | sortBlock value: node1 element value: node2 element ] ]. + html + unorderedList: [ + sortedChildren + doWithIndex: [ :child :index | + self + renderListTree: child + index: parentIndex asString, ':', index asString + indentedBy: anInteger + 1 + on: html ] ] +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> rightIconBlock [ + ^ rightIconBlock +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> rightIconBlock: anObject [ + rightIconBlock := anObject +] diff --git a/src/Material-Design-Lite-Widgets/MDLNestedListItemRenderAjaxStrategy.class.st b/src/Material-Design-Lite-Widgets/MDLNestedListItemRenderAjaxStrategy.class.st index 1ae9b1a3..74a8fcd4 100644 --- a/src/Material-Design-Lite-Widgets/MDLNestedListItemRenderAjaxStrategy.class.st +++ b/src/Material-Design-Lite-Widgets/MDLNestedListItemRenderAjaxStrategy.class.st @@ -1,22 +1,22 @@ -Class { - #name : #MDLNestedListItemRenderAjaxStrategy, - #superclass : #MDLNestedListItemRenderAbstractStrategy, - #category : #'Material-Design-Lite-Widgets-List' -} - -{ #category : #'as yet unclassified' } -MDLNestedListItemRenderAjaxStrategy >> asAjaxStrategy [ - ^ self -] - -{ #category : #'as yet unclassified' } -MDLNestedListItemRenderAjaxStrategy >> getHtmlElementForNode: aNode inDiv: div index: anIndex indentedBy: anInteger on: html [ - ^ html div - onClick: (self actionBlock cull: aNode element). -] - -{ #category : #'as yet unclassified' } -MDLNestedListItemRenderAjaxStrategy >> initialize [ - super initialize. - self isJsAction: true -] +Class { + #name : #MDLNestedListItemRenderAjaxStrategy, + #superclass : #MDLNestedListItemRenderAbstractStrategy, + #category : #'Material-Design-Lite-Widgets-List' +} + +{ #category : #'as yet unclassified' } +MDLNestedListItemRenderAjaxStrategy >> asAjaxStrategy [ + ^ self +] + +{ #category : #'as yet unclassified' } +MDLNestedListItemRenderAjaxStrategy >> getHtmlElementForNode: aNode inDiv: div index: anIndex indentedBy: anInteger on: html [ + ^ html div + onClick: (self actionBlock cull: aNode element). +] + +{ #category : #'as yet unclassified' } +MDLNestedListItemRenderAjaxStrategy >> initialize [ + super initialize. + self isJsAction: true +] diff --git a/src/Material-Design-Lite-Widgets/MDLNestedListItemRenderAnchorStrategy.class.st b/src/Material-Design-Lite-Widgets/MDLNestedListItemRenderAnchorStrategy.class.st index 691f1ad5..8e42c29b 100644 --- a/src/Material-Design-Lite-Widgets/MDLNestedListItemRenderAnchorStrategy.class.st +++ b/src/Material-Design-Lite-Widgets/MDLNestedListItemRenderAnchorStrategy.class.st @@ -1,56 +1,56 @@ -Class { - #name : #MDLNestedListItemRenderAnchorStrategy, - #superclass : #MDLNestedListItemRenderAbstractStrategy, - #category : #'Material-Design-Lite-Widgets-List' -} - -{ #category : #'as yet unclassified' } -MDLNestedListItemRenderAnchorStrategy >> asAjaxStrategy [ - ^ MDLNestedListItemRenderAjaxStrategy new - isJsAction: isJsAction; - actionBlock: actionBlock; - helpBlock: helpBlock; - childrenBlock: childrenBlock; - childrenSortBlock: childrenSortBlock; - entryCustomizationHook: entryCustomizationHook; - format: format; - iconBlock: iconBlock; - rightIconBlock: rightIconBlock; - yourself -] - -{ #category : #'as yet unclassified' } -MDLNestedListItemRenderAnchorStrategy >> getHtmlElementForNode: aNode inDiv: div index: anIndex indentedBy: anInteger on: html [ - | anchor | - anchor := html anchor. - self actionBlock - ifNotNil: [ self isJsAction - ifTrue: [ anchor - onClick: - (self - overwriteOnCompleteForNode: aNode - inDiv: div - index: anIndex - indentedBy: anInteger - on: html) ] - ifFalse: [ anchor callback: [ self actionBlock value: aNode element ] ] ]. - ^ anchor -] - -{ #category : #rendering } -MDLNestedListItemRenderAnchorStrategy >> overwriteOnCompleteForNode: aNode inDiv: div index: anIndex indentedBy: anInteger on: html [ - | onClickValue selfOnComplete finalOnComplete | - onClickValue := self actionBlock value: aNode element. - selfOnComplete := (html jQuery id: div) load - html: [ :ajaxHtml | - self - renderItemContentOf: aNode - index: anIndex - indentedBy: anInteger - on: ajaxHtml ]. - [ finalOnComplete := selfOnComplete onComplete: (onClickValue options - at: 'complete' )] - on: GRError do: [ finalOnComplete := selfOnComplete ]. - onClickValue onComplete: finalOnComplete. - ^ onClickValue -] +Class { + #name : #MDLNestedListItemRenderAnchorStrategy, + #superclass : #MDLNestedListItemRenderAbstractStrategy, + #category : #'Material-Design-Lite-Widgets-List' +} + +{ #category : #'as yet unclassified' } +MDLNestedListItemRenderAnchorStrategy >> asAjaxStrategy [ + ^ MDLNestedListItemRenderAjaxStrategy new + isJsAction: isJsAction; + actionBlock: actionBlock; + helpBlock: helpBlock; + childrenBlock: childrenBlock; + childrenSortBlock: childrenSortBlock; + entryCustomizationHook: entryCustomizationHook; + format: format; + iconBlock: iconBlock; + rightIconBlock: rightIconBlock; + yourself +] + +{ #category : #'as yet unclassified' } +MDLNestedListItemRenderAnchorStrategy >> getHtmlElementForNode: aNode inDiv: div index: anIndex indentedBy: anInteger on: html [ + | anchor | + anchor := html anchor. + self actionBlock + ifNotNil: [ self isJsAction + ifTrue: [ anchor + onClick: + (self + overwriteOnCompleteForNode: aNode + inDiv: div + index: anIndex + indentedBy: anInteger + on: html) ] + ifFalse: [ anchor callback: [ self actionBlock value: aNode element ] ] ]. + ^ anchor +] + +{ #category : #rendering } +MDLNestedListItemRenderAnchorStrategy >> overwriteOnCompleteForNode: aNode inDiv: div index: anIndex indentedBy: anInteger on: html [ + | onClickValue selfOnComplete finalOnComplete | + onClickValue := self actionBlock value: aNode element. + selfOnComplete := (html jQuery id: div) load + html: [ :ajaxHtml | + self + renderItemContentOf: aNode + index: anIndex + indentedBy: anInteger + on: ajaxHtml ]. + [ finalOnComplete := selfOnComplete onComplete: (onClickValue options + at: 'complete' )] + on: GRError do: [ finalOnComplete := selfOnComplete ]. + onClickValue onComplete: finalOnComplete. + ^ onClickValue +] diff --git a/src/Material-Design-Lite-Widgets/MDLNestedListTreeNode.class.st b/src/Material-Design-Lite-Widgets/MDLNestedListTreeNode.class.st index b291a0aa..2442bb92 100644 --- a/src/Material-Design-Lite-Widgets/MDLNestedListTreeNode.class.st +++ b/src/Material-Design-Lite-Widgets/MDLNestedListTreeNode.class.st @@ -1,67 +1,67 @@ -" -I AM NOT AN USABLE COMPONENT, I AM A TOOL CLASS - -I am an object used when computing children for an element. It regroups the element, its children and a flag if it is the selected branch. -" -Class { - #name : #MDLNestedListTreeNode, - #superclass : #Object, - #instVars : [ - 'list', - 'element', - 'children', - 'selectedBranch' - ], - #category : #'Material-Design-Lite-Widgets-List' -} - -{ #category : #'instance creation' } -MDLNestedListTreeNode class >> list: aNestedList element: anElement [ - ^ self new - list: aNestedList; - element: anElement; - yourself -] - -{ #category : #accessing } -MDLNestedListTreeNode >> children [ - ^ children ifNil: [ children := (self list childrenBlock value: self element) collect: [ :aChild | self list obtainTreeFor: aChild ] ] -] - -{ #category : #accessing } -MDLNestedListTreeNode >> element [ - ^ element -] - -{ #category : #accessing } -MDLNestedListTreeNode >> element: anObject [ - element := anObject -] - -{ #category : #accessing } -MDLNestedListTreeNode >> list [ - ^ list -] - -{ #category : #accessing } -MDLNestedListTreeNode >> list: anObject [ - list := anObject -] - -{ #category : #printing } -MDLNestedListTreeNode >> printOn: aStream [ - super printOn: aStream. - aStream nextPut: $[. - element printOn: aStream. - aStream nextPut: $] -] - -{ #category : #accessing } -MDLNestedListTreeNode >> selectedBranch [ - ^ selectedBranch ifNil: [ selectedBranch := self children anySatisfy: [ :aChild | aChild selectedElement or: [ aChild selectedBranch ] ] ] -] - -{ #category : #accessing } -MDLNestedListTreeNode >> selectedElement [ - ^ element = self list selectedEntity -] +" +I AM NOT AN USABLE COMPONENT, I AM A TOOL CLASS + +I am an object used when computing children for an element. It regroups the element, its children and a flag if it is the selected branch. +" +Class { + #name : #MDLNestedListTreeNode, + #superclass : #Object, + #instVars : [ + 'list', + 'element', + 'children', + 'selectedBranch' + ], + #category : #'Material-Design-Lite-Widgets-List' +} + +{ #category : #'instance creation' } +MDLNestedListTreeNode class >> list: aNestedList element: anElement [ + ^ self new + list: aNestedList; + element: anElement; + yourself +] + +{ #category : #accessing } +MDLNestedListTreeNode >> children [ + ^ children ifNil: [ children := (self list childrenBlock value: self element) collect: [ :aChild | self list obtainTreeFor: aChild ] ] +] + +{ #category : #accessing } +MDLNestedListTreeNode >> element [ + ^ element +] + +{ #category : #accessing } +MDLNestedListTreeNode >> element: anObject [ + element := anObject +] + +{ #category : #accessing } +MDLNestedListTreeNode >> list [ + ^ list +] + +{ #category : #accessing } +MDLNestedListTreeNode >> list: anObject [ + list := anObject +] + +{ #category : #printing } +MDLNestedListTreeNode >> printOn: aStream [ + super printOn: aStream. + aStream nextPut: $[. + element printOn: aStream. + aStream nextPut: $] +] + +{ #category : #accessing } +MDLNestedListTreeNode >> selectedBranch [ + ^ selectedBranch ifNil: [ selectedBranch := self children anySatisfy: [ :aChild | aChild selectedElement or: [ aChild selectedBranch ] ] ] +] + +{ #category : #accessing } +MDLNestedListTreeNode >> selectedElement [ + ^ element = self list selectedEntity +] diff --git a/src/Material-Design-Lite-Widgets/MDLNewPasswordWidget.class.st b/src/Material-Design-Lite-Widgets/MDLNewPasswordWidget.class.st index e6dbb486..fdd85568 100644 --- a/src/Material-Design-Lite-Widgets/MDLNewPasswordWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLNewPasswordWidget.class.st @@ -1,150 +1,150 @@ -" -I am a widget for password change -" -Class { - #name : #MDLNewPasswordWidget, - #superclass : #MDLHighLevelWidget, - #instVars : [ - 'currentPassword', - 'newPassword', - 'badPasswordBlock', - 'oldPasswordLabel', - 'newPasswordLabel', - 'onSuccessBlock', - 'confirmPasswordLabel', - 'notMatchingPasswordsBlock', - 'rightOldPassword', - 'pattern', - 'errorMessage' - ], - #category : 'Material-Design-Lite-Widgets' -} - -{ #category : #accessing } -MDLNewPasswordWidget >> badPasswordBlock [ - ^ badPasswordBlock ifNil: [ self error: 'Bad password' ] -] - -{ #category : #accessing } -MDLNewPasswordWidget >> badPasswordBlock: anObject [ - badPasswordBlock := anObject -] - -{ #category : #accessing } -MDLNewPasswordWidget >> confirmPasswordLabel [ - ^ confirmPasswordLabel ifNil: [ newPasswordLabel := 'Confirm password' ] -] - -{ #category : #accessing } -MDLNewPasswordWidget >> confirmPasswordLabel: anObject [ - confirmPasswordLabel := anObject -] - -{ #category : #accessing } -MDLNewPasswordWidget >> currentPassword [ - ^ currentPassword -] - -{ #category : #accessing } -MDLNewPasswordWidget >> currentPassword: anObject [ - currentPassword := anObject -] - -{ #category : #initialization } -MDLNewPasswordWidget >> initialize [ - super initialize. - rightOldPassword := false. - pattern := ''. - errorMessage := '' -] - -{ #category : #accessing } -MDLNewPasswordWidget >> newPassword [ - ^ newPassword -] - -{ #category : #accessing } -MDLNewPasswordWidget >> newPassword: anObject [ - newPassword := anObject -] - -{ #category : #accessing } -MDLNewPasswordWidget >> newPasswordLabel [ - ^ newPasswordLabel ifNil: [ newPasswordLabel := 'New password' ] -] - -{ #category : #accessing } -MDLNewPasswordWidget >> newPasswordLabel: anObject [ - ^ newPasswordLabel := anObject -] - -{ #category : #accessing } -MDLNewPasswordWidget >> notMatchingPasswordsBlock [ - ^ notMatchingPasswordsBlock ifNil: [ self error: 'Passwords don''t match' ] -] - -{ #category : #accessing } -MDLNewPasswordWidget >> notMatchingPasswordsBlock: anObject [ - notMatchingPasswordsBlock := anObject -] - -{ #category : #accessing } -MDLNewPasswordWidget >> oldPasswordLabel [ - ^ oldPasswordLabel ifNil: [ oldPasswordLabel := 'Current password' ] -] - -{ #category : #accessing } -MDLNewPasswordWidget >> oldPasswordLabel: anObject [ - ^ oldPasswordLabel := anObject -] - -{ #category : #accessing } -MDLNewPasswordWidget >> onSuccessBlock [ - ^ onSuccessBlock ifNil: [ ^ [ ] ] -] - -{ #category : #accessing } -MDLNewPasswordWidget >> onSuccessBlock: anObject [ - onSuccessBlock := anObject -] - -{ #category : #options } -MDLNewPasswordWidget >> pattern: aPattern errorMessage: aString [ - pattern := aPattern. - errorMessage := aString -] - -{ #category : #rendering } -MDLNewPasswordWidget >> renderContentOn: html [ - html - render: - (MDLTextFieldWidget new - beFloatingLabel; - type: 'password'; - callback: [ :aString | - rightOldPassword := (MD5 hashMessage: aString) = currentPassword. - rightOldPassword - ifFalse: self badPasswordBlock ]; - label: self oldPasswordLabel; - yourself). - html - render: - (MDLTextFieldWidget new - beFloatingLabel; - type: 'password'; - pattern: pattern errorMessage: errorMessage; - on: #newPassword of: self; - label: self newPasswordLabel; - yourself). - html - render: - (MDLTextFieldWidget new - beFloatingLabel; - type: 'password'; - label: self confirmPasswordLabel; - callback: [ :aString | - aString = newPassword - ifFalse: self notMatchingPasswordsBlock - ifTrue: [ rightOldPassword - ifTrue: [ self onSuccessBlock value: aString ] ] ]) -] +" +I am a widget for password change +" +Class { + #name : #MDLNewPasswordWidget, + #superclass : #MDLHighLevelWidget, + #instVars : [ + 'currentPassword', + 'newPassword', + 'badPasswordBlock', + 'oldPasswordLabel', + 'newPasswordLabel', + 'onSuccessBlock', + 'confirmPasswordLabel', + 'notMatchingPasswordsBlock', + 'rightOldPassword', + 'pattern', + 'errorMessage' + ], + #category : 'Material-Design-Lite-Widgets' +} + +{ #category : #accessing } +MDLNewPasswordWidget >> badPasswordBlock [ + ^ badPasswordBlock ifNil: [ self error: 'Bad password' ] +] + +{ #category : #accessing } +MDLNewPasswordWidget >> badPasswordBlock: anObject [ + badPasswordBlock := anObject +] + +{ #category : #accessing } +MDLNewPasswordWidget >> confirmPasswordLabel [ + ^ confirmPasswordLabel ifNil: [ newPasswordLabel := 'Confirm password' ] +] + +{ #category : #accessing } +MDLNewPasswordWidget >> confirmPasswordLabel: anObject [ + confirmPasswordLabel := anObject +] + +{ #category : #accessing } +MDLNewPasswordWidget >> currentPassword [ + ^ currentPassword +] + +{ #category : #accessing } +MDLNewPasswordWidget >> currentPassword: anObject [ + currentPassword := anObject +] + +{ #category : #initialization } +MDLNewPasswordWidget >> initialize [ + super initialize. + rightOldPassword := false. + pattern := ''. + errorMessage := '' +] + +{ #category : #accessing } +MDLNewPasswordWidget >> newPassword [ + ^ newPassword +] + +{ #category : #accessing } +MDLNewPasswordWidget >> newPassword: anObject [ + newPassword := anObject +] + +{ #category : #accessing } +MDLNewPasswordWidget >> newPasswordLabel [ + ^ newPasswordLabel ifNil: [ newPasswordLabel := 'New password' ] +] + +{ #category : #accessing } +MDLNewPasswordWidget >> newPasswordLabel: anObject [ + ^ newPasswordLabel := anObject +] + +{ #category : #accessing } +MDLNewPasswordWidget >> notMatchingPasswordsBlock [ + ^ notMatchingPasswordsBlock ifNil: [ self error: 'Passwords don''t match' ] +] + +{ #category : #accessing } +MDLNewPasswordWidget >> notMatchingPasswordsBlock: anObject [ + notMatchingPasswordsBlock := anObject +] + +{ #category : #accessing } +MDLNewPasswordWidget >> oldPasswordLabel [ + ^ oldPasswordLabel ifNil: [ oldPasswordLabel := 'Current password' ] +] + +{ #category : #accessing } +MDLNewPasswordWidget >> oldPasswordLabel: anObject [ + ^ oldPasswordLabel := anObject +] + +{ #category : #accessing } +MDLNewPasswordWidget >> onSuccessBlock [ + ^ onSuccessBlock ifNil: [ ^ [ ] ] +] + +{ #category : #accessing } +MDLNewPasswordWidget >> onSuccessBlock: anObject [ + onSuccessBlock := anObject +] + +{ #category : #options } +MDLNewPasswordWidget >> pattern: aPattern errorMessage: aString [ + pattern := aPattern. + errorMessage := aString +] + +{ #category : #rendering } +MDLNewPasswordWidget >> renderContentOn: html [ + html + render: + (MDLTextFieldWidget new + beFloatingLabel; + type: 'password'; + callback: [ :aString | + rightOldPassword := (MD5 hashMessage: aString) = currentPassword. + rightOldPassword + ifFalse: self badPasswordBlock ]; + label: self oldPasswordLabel; + yourself). + html + render: + (MDLTextFieldWidget new + beFloatingLabel; + type: 'password'; + pattern: pattern errorMessage: errorMessage; + on: #newPassword of: self; + label: self newPasswordLabel; + yourself). + html + render: + (MDLTextFieldWidget new + beFloatingLabel; + type: 'password'; + label: self confirmPasswordLabel; + callback: [ :aString | + aString = newPassword + ifFalse: self notMatchingPasswordsBlock + ifTrue: [ rightOldPassword + ifTrue: [ self onSuccessBlock value: aString ] ] ]) +] diff --git a/src/Material-Design-Lite-Widgets/MDLNilLayoutSection.class.st b/src/Material-Design-Lite-Widgets/MDLNilLayoutSection.class.st index dae63fe9..40cddedb 100644 --- a/src/Material-Design-Lite-Widgets/MDLNilLayoutSection.class.st +++ b/src/Material-Design-Lite-Widgets/MDLNilLayoutSection.class.st @@ -1,10 +1,10 @@ -Class { - #name : #MDLNilLayoutSection, - #superclass : #MDLAbstractLayoutSection, - #category : 'Material-Design-Lite-Widgets-Header' -} - -{ #category : #'as yet unclassified' } -MDLNilLayoutSection >> renderContentOn: html [ - "do nothing" -] +Class { + #name : #MDLNilLayoutSection, + #superclass : #MDLAbstractLayoutSection, + #category : 'Material-Design-Lite-Widgets-Header' +} + +{ #category : #'as yet unclassified' } +MDLNilLayoutSection >> renderContentOn: html [ + "do nothing" +] diff --git a/src/Material-Design-Lite-Widgets/MDLNumericColumnDescription.class.st b/src/Material-Design-Lite-Widgets/MDLNumericColumnDescription.class.st index d2ccaa27..31d45bac 100644 --- a/src/Material-Design-Lite-Widgets/MDLNumericColumnDescription.class.st +++ b/src/Material-Design-Lite-Widgets/MDLNumericColumnDescription.class.st @@ -1,25 +1,25 @@ -" -I model a numeric column. - -My values are of kind numeric. Because of that, I align the title of the column on the right side. -" -Class { - #name : #MDLNumericColumnDescription, - #superclass : #MDLTableColumnDescription, - #category : #'Material-Design-Lite-Widgets-Table' -} - -{ #category : #rendering } -MDLNumericColumnDescription >> render: row on: html [ - html mdlTableCell - id: (self generateIdUsing: html); - class: 'mdl-table-widget__cell--numeric'; - with: (self evaluation value: row) -] - -{ #category : #rendering } -MDLNumericColumnDescription >> renderHeadingOn: html [ - (super renderHeadingOn: html) - class: 'mdl-table-widget__cell--numeric'; - with: self title. -] +" +I model a numeric column. + +My values are of kind numeric. Because of that, I align the title of the column on the right side. +" +Class { + #name : #MDLNumericColumnDescription, + #superclass : #MDLTableColumnDescription, + #category : #'Material-Design-Lite-Widgets-Table' +} + +{ #category : #rendering } +MDLNumericColumnDescription >> render: row on: html [ + html mdlTableCell + id: (self generateIdUsing: html); + class: 'mdl-table-widget__cell--numeric'; + with: (self evaluation value: row) +] + +{ #category : #rendering } +MDLNumericColumnDescription >> renderHeadingOn: html [ + (super renderHeadingOn: html) + class: 'mdl-table-widget__cell--numeric'; + with: self title. +] diff --git a/src/Material-Design-Lite-Widgets/MDLPoll.class.st b/src/Material-Design-Lite-Widgets/MDLPoll.class.st index ffed4df8..eca00582 100644 --- a/src/Material-Design-Lite-Widgets/MDLPoll.class.st +++ b/src/Material-Design-Lite-Widgets/MDLPoll.class.st @@ -1,61 +1,61 @@ -" -I am the model for MDLPollWidget. - -I just store the number of positive and negative count. -" -Class { - #name : #MDLPoll, - #superclass : #GRObject, - #instVars : [ - 'positiveCount', - 'negativeCount' - ], - #category : #'Material-Design-Lite-Widgets-Poll' -} - -{ #category : #accessing } -MDLPoll >> decreaseNegativeCount [ - negativeCount := negativeCount - 1 -] - -{ #category : #accessing } -MDLPoll >> decreasePositiveCount [ - positiveCount := positiveCount - 1 -] - -{ #category : #accessing } -MDLPoll >> increaseNegativeCount [ - negativeCount := negativeCount + 1 -] - -{ #category : #accessing } -MDLPoll >> increasePositiveCount [ - positiveCount := positiveCount + 1 -] - -{ #category : #initialization } -MDLPoll >> initialize [ - super initialize. - positiveCount := 0. - negativeCount := 0 -] - -{ #category : #accessing } -MDLPoll >> negativeCount [ - ^ negativeCount -] - -{ #category : #accessing } -MDLPoll >> negativeCount: anObject [ - negativeCount := anObject -] - -{ #category : #accessing } -MDLPoll >> positiveCount [ - ^ positiveCount -] - -{ #category : #accessing } -MDLPoll >> positiveCount: anObject [ - positiveCount := anObject -] +" +I am the model for MDLPollWidget. + +I just store the number of positive and negative count. +" +Class { + #name : #MDLPoll, + #superclass : #GRObject, + #instVars : [ + 'positiveCount', + 'negativeCount' + ], + #category : #'Material-Design-Lite-Widgets-Poll' +} + +{ #category : #accessing } +MDLPoll >> decreaseNegativeCount [ + negativeCount := negativeCount - 1 +] + +{ #category : #accessing } +MDLPoll >> decreasePositiveCount [ + positiveCount := positiveCount - 1 +] + +{ #category : #accessing } +MDLPoll >> increaseNegativeCount [ + negativeCount := negativeCount + 1 +] + +{ #category : #accessing } +MDLPoll >> increasePositiveCount [ + positiveCount := positiveCount + 1 +] + +{ #category : #initialization } +MDLPoll >> initialize [ + super initialize. + positiveCount := 0. + negativeCount := 0 +] + +{ #category : #accessing } +MDLPoll >> negativeCount [ + ^ negativeCount +] + +{ #category : #accessing } +MDLPoll >> negativeCount: anObject [ + negativeCount := anObject +] + +{ #category : #accessing } +MDLPoll >> positiveCount [ + ^ positiveCount +] + +{ #category : #accessing } +MDLPoll >> positiveCount: anObject [ + positiveCount := anObject +] diff --git a/src/Material-Design-Lite-Widgets/MDLPollWidget.class.st b/src/Material-Design-Lite-Widgets/MDLPollWidget.class.st index 65a8ee43..b87132f1 100644 --- a/src/Material-Design-Lite-Widgets/MDLPollWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLPollWidget.class.st @@ -1,98 +1,98 @@ -" -I represent a widget for polling with thumbs. - -For you project, you must subclass me and override #negativePollBlock and #positivePollBlock -" -Class { - #name : #MDLPollWidget, - #superclass : #MDLHighLevelWidget, - #instVars : [ - 'model' - ], - #category : #'Material-Design-Lite-Widgets-Poll' -} - -{ #category : #'instance creation' } -MDLPollWidget class >> newWithPoll: aMDLPoll [ - ^ self new poll: aMDLPoll -] - -{ #category : #adding } -MDLPollWidget >> addNegativeVote [ - model increaseNegativeCount -] - -{ #category : #adding } -MDLPollWidget >> addPositiveVote [ - model increasePositiveCount -] - -{ #category : #initialization } -MDLPollWidget >> initialize [ - super initialize. - self class: 'mdl-poll-widget'. - model := MDLPoll new -] - -{ #category : #javascript } -MDLPollWidget >> jsNegativeButtonClickedOn: html [ - ^ (html jQuery id: self id) load - html: [ :ajaxHtml | - self addNegativeVote. - self renderPollButtonsOn: ajaxHtml ] -] - -{ #category : #javascript } -MDLPollWidget >> jsPositiveButtonClickedOn: html [ - ^ (html jQuery id: self id) load - html: [ :ajaxHtml | - self addPositiveVote. - self renderPollButtonsOn: ajaxHtml ] -] - -{ #category : #accessing } -MDLPollWidget >> model [ - ^ model -] - -{ #category : #accessing } -MDLPollWidget >> poll: aPoll [ - model := aPoll -] - -{ #category : #rendering } -MDLPollWidget >> renderContentOn: html [ - self ensureId: html. - html div - id: self id; - with: [ self renderPollButtonsOn: html ] -] - -{ #category : #rendering } -MDLPollWidget >> renderNegativePollButtonOn: html [ - html mdlIconBadge - overlap; - dataBadge: model negativeCount greaseString; - with: [ html mdlButton - rippleEffect; - onClick: (self jsNegativeButtonClickedOn: html); - icon: 'thumb_down' ] -] - -{ #category : #rendering } -MDLPollWidget >> renderPollButtonsOn: html [ - self renderPositivePollButtonOn: html. - self renderNegativePollButtonOn: html -] - -{ #category : #rendering } -MDLPollWidget >> renderPositivePollButtonOn: html [ - html mdlIconBadge - overlap; - dataBadge: model positiveCount greaseString; - with: [ html mdlButton - rippleEffect; - icon; - onClick: (self jsPositiveButtonClickedOn: html); - icon: 'thumb_up' ] -] +" +I represent a widget for polling with thumbs. + +For you project, you must subclass me and override #negativePollBlock and #positivePollBlock +" +Class { + #name : #MDLPollWidget, + #superclass : #MDLHighLevelWidget, + #instVars : [ + 'model' + ], + #category : #'Material-Design-Lite-Widgets-Poll' +} + +{ #category : #'instance creation' } +MDLPollWidget class >> newWithPoll: aMDLPoll [ + ^ self new poll: aMDLPoll +] + +{ #category : #adding } +MDLPollWidget >> addNegativeVote [ + model increaseNegativeCount +] + +{ #category : #adding } +MDLPollWidget >> addPositiveVote [ + model increasePositiveCount +] + +{ #category : #initialization } +MDLPollWidget >> initialize [ + super initialize. + self class: 'mdl-poll-widget'. + model := MDLPoll new +] + +{ #category : #javascript } +MDLPollWidget >> jsNegativeButtonClickedOn: html [ + ^ (html jQuery id: self id) load + html: [ :ajaxHtml | + self addNegativeVote. + self renderPollButtonsOn: ajaxHtml ] +] + +{ #category : #javascript } +MDLPollWidget >> jsPositiveButtonClickedOn: html [ + ^ (html jQuery id: self id) load + html: [ :ajaxHtml | + self addPositiveVote. + self renderPollButtonsOn: ajaxHtml ] +] + +{ #category : #accessing } +MDLPollWidget >> model [ + ^ model +] + +{ #category : #accessing } +MDLPollWidget >> poll: aPoll [ + model := aPoll +] + +{ #category : #rendering } +MDLPollWidget >> renderContentOn: html [ + self ensureId: html. + html div + id: self id; + with: [ self renderPollButtonsOn: html ] +] + +{ #category : #rendering } +MDLPollWidget >> renderNegativePollButtonOn: html [ + html mdlIconBadge + overlap; + dataBadge: model negativeCount greaseString; + with: [ html mdlButton + rippleEffect; + onClick: (self jsNegativeButtonClickedOn: html); + icon: 'thumb_down' ] +] + +{ #category : #rendering } +MDLPollWidget >> renderPollButtonsOn: html [ + self renderPositivePollButtonOn: html. + self renderNegativePollButtonOn: html +] + +{ #category : #rendering } +MDLPollWidget >> renderPositivePollButtonOn: html [ + html mdlIconBadge + overlap; + dataBadge: model positiveCount greaseString; + with: [ html mdlButton + rippleEffect; + icon; + onClick: (self jsPositiveButtonClickedOn: html); + icon: 'thumb_up' ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLProgressBarWidget.class.st b/src/Material-Design-Lite-Widgets/MDLProgressBarWidget.class.st index 9dd7e3c8..d9eda883 100644 --- a/src/Material-Design-Lite-Widgets/MDLProgressBarWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLProgressBarWidget.class.st @@ -1,128 +1,128 @@ -" -Description --------------------- - -I am a widget that display a progress bar. This progress bar will be linked to a progression block. - -Public API and Key Messages --------------------- - -- #hidden To hide the progress bar at the page oppening - -Examples --------------------- - - - -Internal Representation and Key Implementation Points. --------------------- - - Instance Variables - hyde: If true, the progress bar will be hidden at the rendering - progressionBlock: This must have 0 parameter. It will be evaluated each time to know the progression of the bar. The returned value must be within 0 and 1. - refreshTime: The time between two evaluations of the progression block. A short time will refresh the bar more ofter but will require more work from the server - -" -Class { - #name : #MDLProgressBarWidget, - #superclass : #MDLWidget, - #instVars : [ - 'progressionBlock', - 'refreshTime', - 'hide' - ], - #category : #'Material-Design-Lite-Widgets-Loading' -} - -{ #category : #'instance creation' } -MDLProgressBarWidget class >> progression: aProgressionBlock [ - ^ self new - progressionBlock: aProgressionBlock; - yourself -] - -{ #category : #'instance creation' } -MDLProgressBarWidget class >> progression: aProgressionBlock every: aDuration [ - ^ self new - progressionBlock: aProgressionBlock; - refreshTime: aDuration; - yourself -] - -{ #category : #options } -MDLProgressBarWidget >> hidden [ - self hide: true -] - -{ #category : #accessing } -MDLProgressBarWidget >> hide [ - ^ hide -] - -{ #category : #accessing } -MDLProgressBarWidget >> hide: aBoolean [ - hide := aBoolean -] - -{ #category : #initialization } -MDLProgressBarWidget >> initialize [ - super initialize. - self refreshTime: 1 seconds. - self hide: false -] - -{ #category : #javascript } -MDLProgressBarWidget >> progressScript: html [ - self flag: #todo. "Cyril: I think we can clean a little this part. Maybe it should go partly in a javascript file" - ^ html document - addLoadScript: - ('var interval' , id , ' = setInterval(function(){') js - , - (html jQuery getJson - json: [ :json | - json - object: [ json key: #progress value: ((100 * self progressionBlock value) asInteger min: 100) ] ]; - onSuccess: - 'if(arguments[0].progress >= 100) window.clearInterval(interval' , id - , - '); - document.querySelector(''#' , id - , ''').MaterialProgress.setProgress(arguments[0].progress);') - , (';}, ' , self refreshTime asMilliSeconds asString , ');') js -] - -{ #category : #accessing } -MDLProgressBarWidget >> progressionBlock [ - ^ progressionBlock -] - -{ #category : #accessing } -MDLProgressBarWidget >> progressionBlock: aBlock [ - progressionBlock := aBlock -] - -{ #category : #accessing } -MDLProgressBarWidget >> refreshTime [ - ^ refreshTime -] - -{ #category : #accessing } -MDLProgressBarWidget >> refreshTime: aDuration [ - refreshTime := aDuration -] - -{ #category : #rendering } -MDLProgressBarWidget >> renderContentOn: html [ - self ensureId: html. - self flag: #todo. "This need some cleaning." - "The style should be in a css file" - html mdlProgressBar - style: 'margin: auto;' , (self hide ifTrue: [ 'display: none;' ] ifFalse: [ '' ]); - id: id. - self hide ifFalse: [ self progressScript: html ] -] - -{ #category : #javascript } -MDLProgressBarWidget >> showScript: html [ - ^ (html jQuery id: self id) show , (self progressScript: html) -] +" +Description +-------------------- + +I am a widget that display a progress bar. This progress bar will be linked to a progression block. + +Public API and Key Messages +-------------------- + +- #hidden To hide the progress bar at the page oppening + +Examples +-------------------- + + + +Internal Representation and Key Implementation Points. +-------------------- + + Instance Variables + hyde: If true, the progress bar will be hidden at the rendering + progressionBlock: This must have 0 parameter. It will be evaluated each time to know the progression of the bar. The returned value must be within 0 and 1. + refreshTime: The time between two evaluations of the progression block. A short time will refresh the bar more ofter but will require more work from the server + +" +Class { + #name : #MDLProgressBarWidget, + #superclass : #MDLWidget, + #instVars : [ + 'progressionBlock', + 'refreshTime', + 'hide' + ], + #category : #'Material-Design-Lite-Widgets-Loading' +} + +{ #category : #'instance creation' } +MDLProgressBarWidget class >> progression: aProgressionBlock [ + ^ self new + progressionBlock: aProgressionBlock; + yourself +] + +{ #category : #'instance creation' } +MDLProgressBarWidget class >> progression: aProgressionBlock every: aDuration [ + ^ self new + progressionBlock: aProgressionBlock; + refreshTime: aDuration; + yourself +] + +{ #category : #options } +MDLProgressBarWidget >> hidden [ + self hide: true +] + +{ #category : #accessing } +MDLProgressBarWidget >> hide [ + ^ hide +] + +{ #category : #accessing } +MDLProgressBarWidget >> hide: aBoolean [ + hide := aBoolean +] + +{ #category : #initialization } +MDLProgressBarWidget >> initialize [ + super initialize. + self refreshTime: 1 seconds. + self hide: false +] + +{ #category : #javascript } +MDLProgressBarWidget >> progressScript: html [ + self flag: #todo. "Cyril: I think we can clean a little this part. Maybe it should go partly in a javascript file" + ^ html document + addLoadScript: + ('var interval' , id , ' = setInterval(function(){') js + , + (html jQuery getJson + json: [ :json | + json + object: [ json key: #progress value: ((100 * self progressionBlock value) asInteger min: 100) ] ]; + onSuccess: + 'if(arguments[0].progress >= 100) window.clearInterval(interval' , id + , + '); + document.querySelector(''#' , id + , ''').MaterialProgress.setProgress(arguments[0].progress);') + , (';}, ' , self refreshTime asMilliSeconds asString , ');') js +] + +{ #category : #accessing } +MDLProgressBarWidget >> progressionBlock [ + ^ progressionBlock +] + +{ #category : #accessing } +MDLProgressBarWidget >> progressionBlock: aBlock [ + progressionBlock := aBlock +] + +{ #category : #accessing } +MDLProgressBarWidget >> refreshTime [ + ^ refreshTime +] + +{ #category : #accessing } +MDLProgressBarWidget >> refreshTime: aDuration [ + refreshTime := aDuration +] + +{ #category : #rendering } +MDLProgressBarWidget >> renderContentOn: html [ + self ensureId: html. + self flag: #todo. "This need some cleaning." + "The style should be in a css file" + html mdlProgressBar + style: 'margin: auto;' , (self hide ifTrue: [ 'display: none;' ] ifFalse: [ '' ]); + id: id. + self hide ifFalse: [ self progressScript: html ] +] + +{ #category : #javascript } +MDLProgressBarWidget >> showScript: html [ + ^ (html jQuery id: self id) show , (self progressScript: html) +] diff --git a/src/Material-Design-Lite-Widgets/MDLPseudoRegexFilter.class.st b/src/Material-Design-Lite-Widgets/MDLPseudoRegexFilter.class.st index d35b35b5..47ff8265 100644 --- a/src/Material-Design-Lite-Widgets/MDLPseudoRegexFilter.class.st +++ b/src/Material-Design-Lite-Widgets/MDLPseudoRegexFilter.class.st @@ -1,31 +1,31 @@ -" -I am a nested list filter keeping only elements whose name includes the pattern of the user. BUT! If the pattern contains a ""*"" or a ""#"", I uses a regex fiter. -" -Class { - #name : #MDLPseudoRegexFilter, - #superclass : #MDLAbstractFilter, - #category : 'Material-Design-Lite-Widgets-List' -} - -{ #category : #accessing } -MDLPseudoRegexFilter class >> adaptPattern: aPattern [ - ^ String - streamContents: [ :s | - (aPattern includes: $*) - ifFalse: [ s nextPutAll: '.*' ]. - s nextPutAll: ('.*' join: ($* split: aPattern)). - (aPattern includes: $*) - ifFalse: [ s nextPutAll: '.*' ] ] -] - -{ #category : #accessing } -MDLPseudoRegexFilter class >> formatedElement: aString matches: aRegex [ - ^ aRegex matches: aString -] - -{ #category : #accessing } -MDLPseudoRegexFilter class >> selectMatchingFrom: aCollection format: aFormatBlock with: aPattern [ - | regex | - regex := (self adaptPattern: aPattern) asRegexIgnoringCase. - ^ aCollection select: [ :each | self formatedElement: (aFormatBlock value: each) matches: regex ] -] +" +I am a nested list filter keeping only elements whose name includes the pattern of the user. BUT! If the pattern contains a ""*"" or a ""#"", I uses a regex fiter. +" +Class { + #name : #MDLPseudoRegexFilter, + #superclass : #MDLAbstractFilter, + #category : 'Material-Design-Lite-Widgets-List' +} + +{ #category : #accessing } +MDLPseudoRegexFilter class >> adaptPattern: aPattern [ + ^ String + streamContents: [ :s | + (aPattern includes: $*) + ifFalse: [ s nextPutAll: '.*' ]. + s nextPutAll: ('.*' join: ($* split: aPattern)). + (aPattern includes: $*) + ifFalse: [ s nextPutAll: '.*' ] ] +] + +{ #category : #accessing } +MDLPseudoRegexFilter class >> formatedElement: aString matches: aRegex [ + ^ aRegex matches: aString +] + +{ #category : #accessing } +MDLPseudoRegexFilter class >> selectMatchingFrom: aCollection format: aFormatBlock with: aPattern [ + | regex | + regex := (self adaptPattern: aPattern) asRegexIgnoringCase. + ^ aCollection select: [ :each | self formatedElement: (aFormatBlock value: each) matches: regex ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLSelectWidget.class.st b/src/Material-Design-Lite-Widgets/MDLSelectWidget.class.st index 0b1bebb5..32736b13 100644 --- a/src/Material-Design-Lite-Widgets/MDLSelectWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLSelectWidget.class.st @@ -1,433 +1,433 @@ -" -I am a widget trying to reproduce the behavior of a select input of a form with a WDL compatible design. - -Description --------------------- - -I am a widget with a list of possibilities that can select the user. - -I MUST be used inside a form and I will execute a callback on the submit. - -I have a tricky implementation, for more informations check the implementations detail at the end of the comment. - -Public API and Key Messages --------------------- - -There is many constructors in my class side. - -- #defaultSorting Use this method to sort the labels using the #<= operator by default -- #beAutoSubmit Use this method if you want to form to submit when the user select a value. Do not forget to put your widget in a form. - -Examples -------------------- - - MDLSelectWidget new - possibilities: #(1 2 3 4 5 5); - labelBlock: [ :number | number = 5 ifTrue: [ '0' ] ifFalse: [ (number - 1) asString ] ]; - choosingText: 'Select Your Number'; - selectedObject: 3; - defaultSorting; - callback: [ :input | Transcript << input; cr ]; - description: 'description'; - beAutoSubmit; - yourself. - - - MDLSelectWidget - possibilities: #(1 2 3 4 5 5) - inputLabel: 'Select Your Number' - labelBlock: [ :number | number = 5 ifTrue: [ '0' ] ifFalse: [ (number - 1) asString ] ] - callback: [ :input | Transcript << input; cr ] - selectedObject: 3 - tooltip: 'description' - sortBlock: [ :a :b | a > b ] - -Internal Representation and Key Implementation Points. -------------------- - - Instance Variables - autoSubmit: If true, the form will be submit when the user select a value - callback: A callback to execute on the form submit. It will take as parameter the selected object. - choosingText: The label of the select input. - customizationBlock: An optional block to customize the text field of the select widget. It will take the mdl brush as parameter and the html canvas. - description: An optional tooltip for the input. - labelBlock: A block taking in parameter an object and returning a label to show in the input. - possibilities: The list of possibilities. - selectedObject: An optional object to select by default. - sortBlock: An optional block to sort the objects. - - -Implementation Points -------------------- - -I act as a select by in fact this is just a trick. In reality I am just an text field in read only. The user cannot enter text but he can select an element of a list. The selected element will replace the text in the input. - -To use the callback I keep a temporary dictionary of all the labels and the associated objects. I should ALWAYS have only one object by label. In case the label block return an existing label, I will add a `(X)` to the label where X is the number of occurences. -" -Class { - #name : #MDLSelectWidget, - #superclass : #MDLWidget, - #instVars : [ - 'choosingText', - 'labelBlock', - 'callback', - 'selectedObject', - 'possibilities', - 'description', - 'sortBlock', - 'autoSubmit', - 'customizationBlock', - 'entryTooltip' - ], - #category : #'Material-Design-Lite-Widgets-Form' -} - -{ #category : #'instance creation' } -MDLSelectWidget class >> possibilities: aColl inputLabel: aLabel labelBlock: aLabelBlock callback: aBlock [ - ^ self - possibilities: aColl - inputLabel: aLabel - labelBlock: aLabelBlock - callback: aBlock - selectedObject: nil -] - -{ #category : #'instance creation' } -MDLSelectWidget class >> possibilities: aColl inputLabel: aLabel labelBlock: aLabelBlock callback: aBlock selectedObject: anObject [ - ^ self - possibilities: aColl - inputLabel: aLabel - labelBlock: aLabelBlock - callback: aBlock - selectedObject: anObject - tooltip: nil -] - -{ #category : #'instance creation' } -MDLSelectWidget class >> possibilities: aColl inputLabel: aLabel labelBlock: aLabelBlock callback: aBlock selectedObject: anObject tooltip: aString [ - ^ self - possibilities: aColl - inputLabel: aLabel - labelBlock: aLabelBlock - callback: aBlock - selectedObject: anObject - tooltip: aString - sortBlock: nil -] - -{ #category : #'instance creation' } -MDLSelectWidget class >> possibilities: aColl inputLabel: aLabel labelBlock: aLabelBlock callback: aBlock selectedObject: anObject tooltip: aString sortBlock: aSortBlock [ - ^ self new - choosingText: aLabel; - labelBlock: aLabelBlock; - callback: aBlock; - selectedObject: anObject; - possibilities: aColl; - description: aString; - sortBlock: aSortBlock; - yourself -] - -{ #category : #'labelMap - generation' } -MDLSelectWidget >> addLabelMapEntryFor: anElem version: anInteger into: aDictionary [ - | label | - label := self labelFor: anElem version: anInteger. - aDictionary at: label ifPresent: [ :lab | self addLabelMapEntryFor: anElem version: anInteger + 1 into: aDictionary ] ifAbsent: [ aDictionary at: label put: anElem ]. - self flag: #pharo6. "at:ifPresent:ifAbsentPut: is only available in Pharo 6 :( Improve this when the minimal Pharo version required will be Pharo 6." - ^ aDictionary -] - -{ #category : #accessing } -MDLSelectWidget >> autoSubmit [ - ^ autoSubmit ifNil: [ autoSubmit := false ] -] - -{ #category : #accessing } -MDLSelectWidget >> autoSubmit: anObject [ - autoSubmit := anObject -] - -{ #category : #'public api' } -MDLSelectWidget >> beAutoSubmit [ - "With this option the select widget will submit on a user selection. Do not forget to put your widget in a form." - - self autoSubmit: true -] - -{ #category : #'labelMap - generation' } -MDLSelectWidget >> buildLabelMap [ - ^ self possibilities - inject: OrderedDictionary new - into: [ :dico :elem | self addLabelMapEntryFor: elem version: 0 into: dico ] -] - -{ #category : #accessing } -MDLSelectWidget >> callback [ - ^ callback -] - -{ #category : #'public api' } -MDLSelectWidget >> callback: aBlockOrSymbol [ - "Callback to execute on the form submit." - - callback := aBlockOrSymbol -] - -{ #category : #accessing } -MDLSelectWidget >> choosingText [ - ^ choosingText -] - -{ #category : #'public api' } -MDLSelectWidget >> choosingText: aString [ - "The label of the select input." - - choosingText := aString -] - -{ #category : #accessing } -MDLSelectWidget >> customizationBlock [ - ^ customizationBlock -] - -{ #category : #accessing } -MDLSelectWidget >> customizationBlock: anObject [ - customizationBlock := anObject -] - -{ #category : #accessing } -MDLSelectWidget >> defaultValueBasedOn: aLabelMap [ - (self selectedObject isNil and: [ self possibilities isEmpty ]) ifTrue: [ ^ nil ]. - - ^ aLabelMap - keyAtValue: (self selectedObject ifNil: [ self possibilities first ]) - ifAbsent: [ self error: 'The selected object is not in the possibilities collection.' ] -] - -{ #category : #accessing } -MDLSelectWidget >> description [ - ^ description -] - -{ #category : #'public api' } -MDLSelectWidget >> description: aString [ - "An optional tooltip for the input." - - description := aString -] - -{ #category : #accessing } -MDLSelectWidget >> entryTooltip [ - ^ entryTooltip -] - -{ #category : #accessing } -MDLSelectWidget >> entryTooltip: aBlockOrSymbol [ - entryTooltip := aBlockOrSymbol -] - -{ #category : #private } -MDLSelectWidget >> idForMenuItemLabelled: aLabel inSelectWith: anId [ - ^ anId , 'entry' , aLabel -] - -{ #category : #initialization } -MDLSelectWidget >> initialize [ - super initialize. - - "In case the user does not set any possibilities, show a disable select widget instead of throwing an error during the redering because the possibilities are nil instead of an empty collection." - possibilities := #() -] - -{ #category : #javascript } -MDLSelectWidget >> jsSelectInitialization [ - ^ 'getmdlSelect.init("#' , self id , '");' - " this ->'document.addEventListener('DOMNodeInserted', function (ev) { componentHandler.upgradeDom(); }, false);' must never add. It's bad pratice. - Launch yourself componentHandler.upgradeDom() OR add ONLY ONE TIME at the document this eventListener" -] - -{ #category : #accessing } -MDLSelectWidget >> labelBlock [ - ^ labelBlock -] - -{ #category : #'public api' } -MDLSelectWidget >> labelBlock: aBlockOrSymbol [ - "A block taking in parameter an object and returning a label to show in the input." - - labelBlock := aBlockOrSymbol -] - -{ #category : #accessing } -MDLSelectWidget >> labelFor: anObject [ - ^ self labelBlock ifNil: [ anObject asString ] ifNotNil: [ :blk | blk value: anObject ] -] - -{ #category : #'labelMap - generation' } -MDLSelectWidget >> labelFor: anElem version: anInteger [ - ^ String - streamContents: [ :s | - s nextPutAll: (self labelFor: anElem). - anInteger = 0 - ifFalse: [ s - nextPutAll: ' ('; - print: anInteger; - nextPut: $) ] ] -] - -{ #category : #'public api - seaside compatibility' } -MDLSelectWidget >> labels: aBlockOrSymbol [ - "This method is here to match at least a minimum with the seaside select API." - - self labelBlock: aBlockOrSymbol -] - -{ #category : #'public api - seaside compatibility' } -MDLSelectWidget >> list: aCollection [ - "This method is here to match at least a minimum with the seaside select API." - - self possibilities: aCollection -] - -{ #category : #accessing } -MDLSelectWidget >> possibilities [ - ^ possibilities -] - -{ #category : #'public api' } -MDLSelectWidget >> possibilities: aCollection [ - "The list of possibilities." - - possibilities := aCollection -] - -{ #category : #rendering } -MDLSelectWidget >> renderArrowIconFor: anId on: html [ - html label - for: anId; - with: [ html mdlIcon - toggle; - with: #keyboard_arrow_down ] -] - -{ #category : #rendering } -MDLSelectWidget >> renderContentOn: html [ - self ensureId: html. - html mdlTextFieldContainer - class: #'mdl-select'; - id: self id; - floatingLabel; - with: [ | fieldId labelMap | - self - renderTextFieldFor: (fieldId := html nextId) withMap: (labelMap := self buildLabelMap) on: html; - renderArrowIconFor: fieldId on: html; - renderLabelFor: fieldId on: html; - renderPossibilitiesFor: fieldId withMap: labelMap on: html; - renderTooltipFor: fieldId on: html. - labelMap keysAndValuesDo: [ :label :object | self renderMenuTooltipFor: object at: (self idForMenuItemLabelled: label inSelectWith: fieldId) on: html ] ]. - html script: self jsSelectInitialization -] - -{ #category : #rendering } -MDLSelectWidget >> renderLabelFor: anId on: html [ - self choosingText isEmptyOrNil ifTrue: [ ^ self ]. - - html mdlTextFieldLabel - for: anId; - with: self choosingText -] - -{ #category : #rendering } -MDLSelectWidget >> renderMenuTooltipFor: anItem at: anId on: html [ - | helpText | - (self entryTooltip isNil or: [ self entryTooltip argumentCount = 1 and: [ (helpText := self entryTooltip value: anItem) isEmptyOrNil ] ]) ifTrue: [ ^ self ]. - - html mdlTooltip - large; - for: anId; - with: - (self entryTooltip argumentCount = 1 - ifTrue: [ helpText ] - ifFalse: [ self entryTooltip mdlCull: anItem cull: html ]) -] - -{ #category : #rendering } -MDLSelectWidget >> renderPossibilitiesFor: anId withMap: aLabelMap on: html [ - aLabelMap ifEmpty: [ ^ self ]. - - html mdlMenu - for: anId; - bottomLeft; - with: [ (self sortBlock ifNil: [ aLabelMap keys ] ifNotNil: [ :blk | aLabelMap keys sort: blk ]) - do: [ :label | - html mdlMenuItem - id: (self idForMenuItemLabelled: label inSelectWith: anId); - with: label ] ] -] - -{ #category : #rendering } -MDLSelectWidget >> renderTextFieldFor: anId withMap: aLabelMap on: html [ - | textField | - (textField := html mdlTextFieldInput) - id: anId; - value: (self defaultValueBasedOn: aLabelMap); - disabled: self possibilities isEmpty; - readonly: true; - tabIndex: '-1'; - noAutocomplete; - callback: [ :input | self callback ifNotNil: [ :cb | cb value: (aLabelMap at: input) ] ]; - onChange: 'submit()' if: self autoSubmit; - type: 'text'. - self customizationBlock ifNotNil: [ :bl | bl mdlCull: textField cull: html ] -] - -{ #category : #rendering } -MDLSelectWidget >> renderTooltipFor: anId on: html [ - self description ifNil: [ ^ self ]. - - html mdlTooltip - for: anId; - large; - with: - (self description isBlock - ifTrue: [ self description value: html ] - ifFalse: [ self description ]) -] - -{ #category : #'public api - seaside compatibility' } -MDLSelectWidget >> selected: anObject [ - "This method is here to match at least a minimum with the seaside select API." - - self selectedObject: anObject -] - -{ #category : #accessing } -MDLSelectWidget >> selectedObject [ - ^ selectedObject value -] - -{ #category : #'public api' } -MDLSelectWidget >> selectedObject: anObject [ - "An optional object to select by default." - - selectedObject := anObject -] - -{ #category : #accessing } -MDLSelectWidget >> sortBlock [ - ^ sortBlock -] - -{ #category : #'public api' } -MDLSelectWidget >> sortBlock: aBlock [ - "An optional block to sort the objects." - - sortBlock := aBlock -] - -{ #category : #'public api' } -MDLSelectWidget >> standardSorting [ - "Use the default #<= on the objects values directly." - - self sortBlock: [ :a :b | a value <= b value ] -] +" +I am a widget trying to reproduce the behavior of a select input of a form with a WDL compatible design. + +Description +-------------------- + +I am a widget with a list of possibilities that can select the user. + +I MUST be used inside a form and I will execute a callback on the submit. + +I have a tricky implementation, for more informations check the implementations detail at the end of the comment. + +Public API and Key Messages +-------------------- + +There is many constructors in my class side. + +- #defaultSorting Use this method to sort the labels using the #<= operator by default +- #beAutoSubmit Use this method if you want to form to submit when the user select a value. Do not forget to put your widget in a form. + +Examples +------------------- + + MDLSelectWidget new + possibilities: #(1 2 3 4 5 5); + labelBlock: [ :number | number = 5 ifTrue: [ '0' ] ifFalse: [ (number - 1) asString ] ]; + choosingText: 'Select Your Number'; + selectedObject: 3; + defaultSorting; + callback: [ :input | Transcript << input; cr ]; + description: 'description'; + beAutoSubmit; + yourself. + + + MDLSelectWidget + possibilities: #(1 2 3 4 5 5) + inputLabel: 'Select Your Number' + labelBlock: [ :number | number = 5 ifTrue: [ '0' ] ifFalse: [ (number - 1) asString ] ] + callback: [ :input | Transcript << input; cr ] + selectedObject: 3 + tooltip: 'description' + sortBlock: [ :a :b | a > b ] + +Internal Representation and Key Implementation Points. +------------------- + + Instance Variables + autoSubmit: If true, the form will be submit when the user select a value + callback: A callback to execute on the form submit. It will take as parameter the selected object. + choosingText: The label of the select input. + customizationBlock: An optional block to customize the text field of the select widget. It will take the mdl brush as parameter and the html canvas. + description: An optional tooltip for the input. + labelBlock: A block taking in parameter an object and returning a label to show in the input. + possibilities: The list of possibilities. + selectedObject: An optional object to select by default. + sortBlock: An optional block to sort the objects. + + +Implementation Points +------------------- + +I act as a select by in fact this is just a trick. In reality I am just an text field in read only. The user cannot enter text but he can select an element of a list. The selected element will replace the text in the input. + +To use the callback I keep a temporary dictionary of all the labels and the associated objects. I should ALWAYS have only one object by label. In case the label block return an existing label, I will add a `(X)` to the label where X is the number of occurences. +" +Class { + #name : #MDLSelectWidget, + #superclass : #MDLWidget, + #instVars : [ + 'choosingText', + 'labelBlock', + 'callback', + 'selectedObject', + 'possibilities', + 'description', + 'sortBlock', + 'autoSubmit', + 'customizationBlock', + 'entryTooltip' + ], + #category : #'Material-Design-Lite-Widgets-Form' +} + +{ #category : #'instance creation' } +MDLSelectWidget class >> possibilities: aColl inputLabel: aLabel labelBlock: aLabelBlock callback: aBlock [ + ^ self + possibilities: aColl + inputLabel: aLabel + labelBlock: aLabelBlock + callback: aBlock + selectedObject: nil +] + +{ #category : #'instance creation' } +MDLSelectWidget class >> possibilities: aColl inputLabel: aLabel labelBlock: aLabelBlock callback: aBlock selectedObject: anObject [ + ^ self + possibilities: aColl + inputLabel: aLabel + labelBlock: aLabelBlock + callback: aBlock + selectedObject: anObject + tooltip: nil +] + +{ #category : #'instance creation' } +MDLSelectWidget class >> possibilities: aColl inputLabel: aLabel labelBlock: aLabelBlock callback: aBlock selectedObject: anObject tooltip: aString [ + ^ self + possibilities: aColl + inputLabel: aLabel + labelBlock: aLabelBlock + callback: aBlock + selectedObject: anObject + tooltip: aString + sortBlock: nil +] + +{ #category : #'instance creation' } +MDLSelectWidget class >> possibilities: aColl inputLabel: aLabel labelBlock: aLabelBlock callback: aBlock selectedObject: anObject tooltip: aString sortBlock: aSortBlock [ + ^ self new + choosingText: aLabel; + labelBlock: aLabelBlock; + callback: aBlock; + selectedObject: anObject; + possibilities: aColl; + description: aString; + sortBlock: aSortBlock; + yourself +] + +{ #category : #'labelMap - generation' } +MDLSelectWidget >> addLabelMapEntryFor: anElem version: anInteger into: aDictionary [ + | label | + label := self labelFor: anElem version: anInteger. + aDictionary at: label ifPresent: [ :lab | self addLabelMapEntryFor: anElem version: anInteger + 1 into: aDictionary ] ifAbsent: [ aDictionary at: label put: anElem ]. + self flag: #pharo6. "at:ifPresent:ifAbsentPut: is only available in Pharo 6 :( Improve this when the minimal Pharo version required will be Pharo 6." + ^ aDictionary +] + +{ #category : #accessing } +MDLSelectWidget >> autoSubmit [ + ^ autoSubmit ifNil: [ autoSubmit := false ] +] + +{ #category : #accessing } +MDLSelectWidget >> autoSubmit: anObject [ + autoSubmit := anObject +] + +{ #category : #'public api' } +MDLSelectWidget >> beAutoSubmit [ + "With this option the select widget will submit on a user selection. Do not forget to put your widget in a form." + + self autoSubmit: true +] + +{ #category : #'labelMap - generation' } +MDLSelectWidget >> buildLabelMap [ + ^ self possibilities + inject: OrderedDictionary new + into: [ :dico :elem | self addLabelMapEntryFor: elem version: 0 into: dico ] +] + +{ #category : #accessing } +MDLSelectWidget >> callback [ + ^ callback +] + +{ #category : #'public api' } +MDLSelectWidget >> callback: aBlockOrSymbol [ + "Callback to execute on the form submit." + + callback := aBlockOrSymbol +] + +{ #category : #accessing } +MDLSelectWidget >> choosingText [ + ^ choosingText +] + +{ #category : #'public api' } +MDLSelectWidget >> choosingText: aString [ + "The label of the select input." + + choosingText := aString +] + +{ #category : #accessing } +MDLSelectWidget >> customizationBlock [ + ^ customizationBlock +] + +{ #category : #accessing } +MDLSelectWidget >> customizationBlock: anObject [ + customizationBlock := anObject +] + +{ #category : #accessing } +MDLSelectWidget >> defaultValueBasedOn: aLabelMap [ + (self selectedObject isNil and: [ self possibilities isEmpty ]) ifTrue: [ ^ nil ]. + + ^ aLabelMap + keyAtValue: (self selectedObject ifNil: [ self possibilities first ]) + ifAbsent: [ self error: 'The selected object is not in the possibilities collection.' ] +] + +{ #category : #accessing } +MDLSelectWidget >> description [ + ^ description +] + +{ #category : #'public api' } +MDLSelectWidget >> description: aString [ + "An optional tooltip for the input." + + description := aString +] + +{ #category : #accessing } +MDLSelectWidget >> entryTooltip [ + ^ entryTooltip +] + +{ #category : #accessing } +MDLSelectWidget >> entryTooltip: aBlockOrSymbol [ + entryTooltip := aBlockOrSymbol +] + +{ #category : #private } +MDLSelectWidget >> idForMenuItemLabelled: aLabel inSelectWith: anId [ + ^ anId , 'entry' , aLabel +] + +{ #category : #initialization } +MDLSelectWidget >> initialize [ + super initialize. + + "In case the user does not set any possibilities, show a disable select widget instead of throwing an error during the redering because the possibilities are nil instead of an empty collection." + possibilities := #() +] + +{ #category : #javascript } +MDLSelectWidget >> jsSelectInitialization [ + ^ 'getmdlSelect.init("#' , self id , '");' + " this ->'document.addEventListener('DOMNodeInserted', function (ev) { componentHandler.upgradeDom(); }, false);' must never add. It's bad pratice. + Launch yourself componentHandler.upgradeDom() OR add ONLY ONE TIME at the document this eventListener" +] + +{ #category : #accessing } +MDLSelectWidget >> labelBlock [ + ^ labelBlock +] + +{ #category : #'public api' } +MDLSelectWidget >> labelBlock: aBlockOrSymbol [ + "A block taking in parameter an object and returning a label to show in the input." + + labelBlock := aBlockOrSymbol +] + +{ #category : #accessing } +MDLSelectWidget >> labelFor: anObject [ + ^ self labelBlock ifNil: [ anObject asString ] ifNotNil: [ :blk | blk value: anObject ] +] + +{ #category : #'labelMap - generation' } +MDLSelectWidget >> labelFor: anElem version: anInteger [ + ^ String + streamContents: [ :s | + s nextPutAll: (self labelFor: anElem). + anInteger = 0 + ifFalse: [ s + nextPutAll: ' ('; + print: anInteger; + nextPut: $) ] ] +] + +{ #category : #'public api - seaside compatibility' } +MDLSelectWidget >> labels: aBlockOrSymbol [ + "This method is here to match at least a minimum with the seaside select API." + + self labelBlock: aBlockOrSymbol +] + +{ #category : #'public api - seaside compatibility' } +MDLSelectWidget >> list: aCollection [ + "This method is here to match at least a minimum with the seaside select API." + + self possibilities: aCollection +] + +{ #category : #accessing } +MDLSelectWidget >> possibilities [ + ^ possibilities +] + +{ #category : #'public api' } +MDLSelectWidget >> possibilities: aCollection [ + "The list of possibilities." + + possibilities := aCollection +] + +{ #category : #rendering } +MDLSelectWidget >> renderArrowIconFor: anId on: html [ + html label + for: anId; + with: [ html mdlIcon + toggle; + with: #keyboard_arrow_down ] +] + +{ #category : #rendering } +MDLSelectWidget >> renderContentOn: html [ + self ensureId: html. + html mdlTextFieldContainer + class: #'mdl-select'; + id: self id; + floatingLabel; + with: [ | fieldId labelMap | + self + renderTextFieldFor: (fieldId := html nextId) withMap: (labelMap := self buildLabelMap) on: html; + renderArrowIconFor: fieldId on: html; + renderLabelFor: fieldId on: html; + renderPossibilitiesFor: fieldId withMap: labelMap on: html; + renderTooltipFor: fieldId on: html. + labelMap keysAndValuesDo: [ :label :object | self renderMenuTooltipFor: object at: (self idForMenuItemLabelled: label inSelectWith: fieldId) on: html ] ]. + html script: self jsSelectInitialization +] + +{ #category : #rendering } +MDLSelectWidget >> renderLabelFor: anId on: html [ + self choosingText isEmptyOrNil ifTrue: [ ^ self ]. + + html mdlTextFieldLabel + for: anId; + with: self choosingText +] + +{ #category : #rendering } +MDLSelectWidget >> renderMenuTooltipFor: anItem at: anId on: html [ + | helpText | + (self entryTooltip isNil or: [ self entryTooltip argumentCount = 1 and: [ (helpText := self entryTooltip value: anItem) isEmptyOrNil ] ]) ifTrue: [ ^ self ]. + + html mdlTooltip + large; + for: anId; + with: + (self entryTooltip argumentCount = 1 + ifTrue: [ helpText ] + ifFalse: [ self entryTooltip mdlCull: anItem cull: html ]) +] + +{ #category : #rendering } +MDLSelectWidget >> renderPossibilitiesFor: anId withMap: aLabelMap on: html [ + aLabelMap ifEmpty: [ ^ self ]. + + html mdlMenu + for: anId; + bottomLeft; + with: [ (self sortBlock ifNil: [ aLabelMap keys ] ifNotNil: [ :blk | aLabelMap keys sort: blk ]) + do: [ :label | + html mdlMenuItem + id: (self idForMenuItemLabelled: label inSelectWith: anId); + with: label ] ] +] + +{ #category : #rendering } +MDLSelectWidget >> renderTextFieldFor: anId withMap: aLabelMap on: html [ + | textField | + (textField := html mdlTextFieldInput) + id: anId; + value: (self defaultValueBasedOn: aLabelMap); + disabled: self possibilities isEmpty; + readonly: true; + tabIndex: '-1'; + noAutocomplete; + callback: [ :input | self callback ifNotNil: [ :cb | cb value: (aLabelMap at: input) ] ]; + onChange: 'submit()' if: self autoSubmit; + type: 'text'. + self customizationBlock ifNotNil: [ :bl | bl mdlCull: textField cull: html ] +] + +{ #category : #rendering } +MDLSelectWidget >> renderTooltipFor: anId on: html [ + self description ifNil: [ ^ self ]. + + html mdlTooltip + for: anId; + large; + with: + (self description isBlock + ifTrue: [ self description value: html ] + ifFalse: [ self description ]) +] + +{ #category : #'public api - seaside compatibility' } +MDLSelectWidget >> selected: anObject [ + "This method is here to match at least a minimum with the seaside select API." + + self selectedObject: anObject +] + +{ #category : #accessing } +MDLSelectWidget >> selectedObject [ + ^ selectedObject value +] + +{ #category : #'public api' } +MDLSelectWidget >> selectedObject: anObject [ + "An optional object to select by default." + + selectedObject := anObject +] + +{ #category : #accessing } +MDLSelectWidget >> sortBlock [ + ^ sortBlock +] + +{ #category : #'public api' } +MDLSelectWidget >> sortBlock: aBlock [ + "An optional block to sort the objects." + + sortBlock := aBlock +] + +{ #category : #'public api' } +MDLSelectWidget >> standardSorting [ + "Use the default #<= on the objects values directly." + + self sortBlock: [ :a :b | a value <= b value ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLSimpleDrawerSection.class.st b/src/Material-Design-Lite-Widgets/MDLSimpleDrawerSection.class.st index 422f3522..1eb2960a 100644 --- a/src/Material-Design-Lite-Widgets/MDLSimpleDrawerSection.class.st +++ b/src/Material-Design-Lite-Widgets/MDLSimpleDrawerSection.class.st @@ -1,12 +1,12 @@ -Class { - #name : #MDLSimpleDrawerSection, - #superclass : #MDLLinkingLayoutSection, - #category : 'Material-Design-Lite-Widgets-Header' -} - -{ #category : #'as yet unclassified' } -MDLSimpleDrawerSection >> renderContentOn: html [ - html mdlLayoutDrawer: [ - html mdlLayoutTitle: layout title. - self renderLinksOn: html ] -] +Class { + #name : #MDLSimpleDrawerSection, + #superclass : #MDLLinkingLayoutSection, + #category : 'Material-Design-Lite-Widgets-Header' +} + +{ #category : #'as yet unclassified' } +MDLSimpleDrawerSection >> renderContentOn: html [ + html mdlLayoutDrawer: [ + html mdlLayoutTitle: layout title. + self renderLinksOn: html ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLSimpleRowHeaderSection.class.st b/src/Material-Design-Lite-Widgets/MDLSimpleRowHeaderSection.class.st index fd9d8768..fe61ad49 100644 --- a/src/Material-Design-Lite-Widgets/MDLSimpleRowHeaderSection.class.st +++ b/src/Material-Design-Lite-Widgets/MDLSimpleRowHeaderSection.class.st @@ -1,15 +1,15 @@ -Class { - #name : #MDLSimpleRowHeaderSection, - #superclass : #MDLAbstractHeaderSection, - #category : 'Material-Design-Lite-Widgets-Header' -} - -{ #category : #rendering } -MDLSimpleRowHeaderSection >> renderContentOn: html [ - (html brush: brush) - with: [ - html - mdlLayoutHeaderRow: [ - html mdlLayoutTitle: layout title. - self renderLinksOn: html ] ] -] +Class { + #name : #MDLSimpleRowHeaderSection, + #superclass : #MDLAbstractHeaderSection, + #category : 'Material-Design-Lite-Widgets-Header' +} + +{ #category : #rendering } +MDLSimpleRowHeaderSection >> renderContentOn: html [ + (html brush: brush) + with: [ + html + mdlLayoutHeaderRow: [ + html mdlLayoutTitle: layout title. + self renderLinksOn: html ] ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLSmallFooter.class.st b/src/Material-Design-Lite-Widgets/MDLSmallFooter.class.st index 47e7ddd5..109833d0 100644 --- a/src/Material-Design-Lite-Widgets/MDLSmallFooter.class.st +++ b/src/Material-Design-Lite-Widgets/MDLSmallFooter.class.st @@ -1,44 +1,44 @@ -" -I'm a Mini Footer. -In this implementation, leftSection is a Dictionary (title -> { label -> url }). -The right section must be a Collection of WAComponents that will be rendered on the right side. -" -Class { - #name : #MDLSmallFooter, - #superclass : #MDLWidget, - #instVars : [ - 'leftSection', - 'rightSection' - ], - #category : #'Material-Design-Lite-Widgets-Footer' -} - -{ #category : #initialization } -MDLSmallFooter >> initialize [ - super initialize. - leftSection := MDLFooterNilSection new. - rightSection := MDLFooterNilSection new -] - -{ #category : #adding } -MDLSmallFooter >> onLeftSideAddLinks: links [ - "Links must be formatted as following : (header -> #((label1->url1) . (label2 -> url2)))" - leftSection isNilSection - ifTrue: [ leftSection := MDLFooterLinksSection new ]. - leftSection := leftSection addLinksList: (MDLMiniFooterLinksList new addLinks: links; yourself) -] - -{ #category : #adding } -MDLSmallFooter >> onRightSideAddComponents: components [ - "Components must be an array of WAComponents (render: will be called on them)" - rightSection isNilSection - ifTrue: [ rightSection := MDLFooterComponentsSection new ]. - rightSection := rightSection addComponents: components -] - -{ #category : #rendering } -MDLSmallFooter >> renderContentOn: html [ - html mdlMiniFooter: [ - html mdlMiniFooterLeftSection: [ leftSection renderSectionOn: html ]. - html mdlMiniFooterRightSection: [ rightSection renderSectionOn: html ] ] -] +" +I'm a Mini Footer. +In this implementation, leftSection is a Dictionary (title -> { label -> url }). +The right section must be a Collection of WAComponents that will be rendered on the right side. +" +Class { + #name : #MDLSmallFooter, + #superclass : #MDLWidget, + #instVars : [ + 'leftSection', + 'rightSection' + ], + #category : #'Material-Design-Lite-Widgets-Footer' +} + +{ #category : #initialization } +MDLSmallFooter >> initialize [ + super initialize. + leftSection := MDLFooterNilSection new. + rightSection := MDLFooterNilSection new +] + +{ #category : #adding } +MDLSmallFooter >> onLeftSideAddLinks: links [ + "Links must be formatted as following : (header -> #((label1->url1) . (label2 -> url2)))" + leftSection isNilSection + ifTrue: [ leftSection := MDLFooterLinksSection new ]. + leftSection := leftSection addLinksList: (MDLMiniFooterLinksList new addLinks: links; yourself) +] + +{ #category : #adding } +MDLSmallFooter >> onRightSideAddComponents: components [ + "Components must be an array of WAComponents (render: will be called on them)" + rightSection isNilSection + ifTrue: [ rightSection := MDLFooterComponentsSection new ]. + rightSection := rightSection addComponents: components +] + +{ #category : #rendering } +MDLSmallFooter >> renderContentOn: html [ + html mdlMiniFooter: [ + html mdlMiniFooterLeftSection: [ leftSection renderSectionOn: html ]. + html mdlMiniFooterRightSection: [ rightSection renderSectionOn: html ] ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLSortableTable.class.st b/src/Material-Design-Lite-Widgets/MDLSortableTable.class.st index 7130e828..30d027d6 100644 --- a/src/Material-Design-Lite-Widgets/MDLSortableTable.class.st +++ b/src/Material-Design-Lite-Widgets/MDLSortableTable.class.st @@ -1,326 +1,326 @@ -" -Sortable table, renders a table and adds the necessary behavior to navigate trough the table - - Instance Variables - elementsToShow: number of rows that will be rendered - header: a table with the table headers ( auto conversion from object ) - position: the index of the first row to render - rows: a table with all the rows - selectable: a boolean saying that the cells can be selected or not - ajaxOnCompleteHook: a String containing some JS code to be executed after we changed of page. By default it will update the MDL components to initialize the new ones. -" -Class { - #name : #MDLSortableTable, - #superclass : #WAComponent, - #instVars : [ - 'title', - 'header', - 'rows', - 'elementsToShow', - 'unsortedRows', - 'position', - 'rowsPerPagePossibilities', - 'selectable', - 'id', - 'ajaxOnCompleteHook', - 'tableStyle', - 'rowsCache' - ], - #category : #'Material-Design-Lite-Widgets-Table' -} - -{ #category : #accessing } -MDLSortableTable >> ajaxOnCompleteHook [ - "I am a hook to let the user add some javascript after the rendering of a new page. By default I will update the MDL components to initialize the new ones that might be in the table if needed." - - ^ ajaxOnCompleteHook ifNil: [ 'componentHandler.upgradeDom();' ] -] - -{ #category : #accessing } -MDLSortableTable >> ajaxOnCompleteHook: anObject [ - ajaxOnCompleteHook := anObject -] - -{ #category : #javascript } -MDLSortableTable >> ajaxUpdateScriptFrom: html [ - ^ html jQuery - script: [ :s | - s - << - ((html jQuery id: id) load - html: [ :ajaxHtml | self renderTableContentOn: ajaxHtml ]; - onComplete: self ajaxOnCompleteHook) ] -] - -{ #category : #accessing } -MDLSortableTable >> elementsToShow [ - ^ elementsToShow -] - -{ #category : #accessing } -MDLSortableTable >> elementsToShow: anObject [ - elementsToShow := anObject -] - -{ #category : #rendering } -MDLSortableTable >> ensureCurrentPageIsVisible [ - "In some case the elements to show can change. If we currently are in a page that does not exist anymore since the number of elements decreased, we should reset the position." - - self position > rowsCache size - ifTrue: [ self position: 1 ] -] - -{ #category : #accessing } -MDLSortableTable >> header [ - ^ header -] - -{ #category : #accessing } -MDLSortableTable >> header: aCollection [ - header := aCollection collect: [ :each | each asMDLSortableTableHeader ] -] - -{ #category : #rendering } -MDLSortableTable >> indexOfLastRowToShow [ - ^ rowsCache size min: position + elementsToShow - 1 -] - -{ #category : #initialization } -MDLSortableTable >> initialize [ - super initialize. - position := 1. - rows := #(). - header := #(). - unsortedRows := #(). - self rowsPerPagePossibilities: #(10 50 100). - selectable := false -] - -{ #category : #actions } -MDLSortableTable >> nextPosition [ - position + elementsToShow < rowsCache size - ifTrue: [ self position: position + elementsToShow ] -] - -{ #category : #accessing } -MDLSortableTable >> noPagination [ - self rowsPerPagePossibilities: {(Float infinity)} -] - -{ #category : #accessing } -MDLSortableTable >> position [ - ^ position -] - -{ #category : #accessing } -MDLSortableTable >> position: anObject [ - position := anObject -] - -{ #category : #actions } -MDLSortableTable >> previousPosition [ - self position: ((position - elementsToShow) max: 1) -] - -{ #category : #rendering } -MDLSortableTable >> renderButtonTriggering: aMethod withIcon: aSymbol disabled: isDisabled on: html [ - html mdlButton - bePush; - colored; - icon; - disabled: isDisabled; - onClick: [ html jQuery ajax - callback: [ self perform: aMethod ]; - onSuccess: (self ajaxUpdateScriptFrom: html) ] - if: isDisabled not; - with: [ html mdlIcon: aSymbol ] -] - -{ #category : #rendering } -MDLSortableTable >> renderContentOn: html [ - html mdlGrid - class: 'mdl-sorted-table'; - with: [ html mdlCard - shadow: 2; - class: 'mdl-sorted-table__wrapper'; - class: self tableStyle if: self tableStyle isNotNil; - id: (id := html nextId); - with: [ self renderTableContentOn: html ] ] -] - -{ #category : #rendering } -MDLSortableTable >> renderFooterPaginationOn: html [ - html mdlCardTextContainer - class: 'mdl-sorted-table__footer'; - with: [ - html div - mdlTypographyTextRight; - with: [ - html text: 'Rows per page: '. - self renderItemsByPageSelectionComponentOn: html. - self renderPagesInfoOn: html. - self - renderButtonTriggering: #previousPosition - withIcon: #keyboard_arrow_left - disabled: position = 1 - on: html. - self - renderButtonTriggering: #nextPosition - withIcon: #keyboard_arrow_right - disabled: position + elementsToShow > rowsCache size - on: html ] ] -] - -{ #category : #rendering } -MDLSortableTable >> renderHeaderOn: html [ - html - tableHead: [ html tableRow: [ header doWithIndex: [ :head :i | head renderContentOn: html forTable: self columnIndex: i ] ] ] -] - -{ #category : #accessing } -MDLSortableTable >> renderItemsByPageSelectionComponentOn: html [ - html - render: - (MDLSelectWidget new - labelBlock: #asString; - possibilities: rowsPerPagePossibilities; - callback: [ :o | self elementsToShow: o ]; - selectedObject: self elementsToShow; - sortBlock: [ :a :b | a asInteger <= b asInteger ]; - customizationBlock: [ :textField :renderer | textField onChange: (html jQuery ajax serializeThis onComplete: (self ajaxUpdateScriptFrom: html)) ]; - yourself) -] - -{ #category : #rendering } -MDLSortableTable >> renderPagesInfoOn: html [ - html - text: - (String - streamContents: [ :s | - s - print: position; - nextPutAll: ' - '; - print: self indexOfLastRowToShow; - nextPutAll: ' of '; - print: rowsCache size ]) -] - -{ #category : #rendering } -MDLSortableTable >> renderRowContentFor: cells on: html [ - header - doWithIndex: [ :headerCell :columnIndex | - | cell | - (headerCell tableCellOn: html) - with: - ((cell := cells at: columnIndex) isBlock - ifTrue: [ [ cell cull: html ] ] - ifFalse: [ cell ]) ] -] - -{ #category : #rendering } -MDLSortableTable >> renderRowsOn: html [ - ((position to: self indexOfLastRowToShow) collect: [ :rowIndex | rowsCache at: rowIndex ]) - do: [ :cells | html tableRow: [ self renderRowContentFor: cells on: html ] ] -] - -{ #category : #rendering } -MDLSortableTable >> renderTableContentOn: html [ - "We cache the rows because it is possible that the user give a block to execute." - - rowsCache := self rows. - self ensureCurrentPageIsVisible. - html div - class: 'mdl-sorted-table__content'; - with: [ self title ifNotNil: [ :t | html mdlCardTitleContainer: [ html mdlCardTitleText: t level: 2 ] ]. - (selectable - ifTrue: [ html mdlTable selectable ] - ifFalse: [ html mdlTable ]) - with: [ self renderHeaderOn: html. - self renderRowsOn: html ] ]. - self shouldDisplayPagination ifTrue: [ self renderFooterPaginationOn: html ] -] - -{ #category : #accessing } -MDLSortableTable >> rows [ - ^ rows value -] - -{ #category : #accessing } -MDLSortableTable >> rows: anObject [ - rows := anObject. - unsortedRows := anObject -] - -{ #category : #accessing } -MDLSortableTable >> rowsPerPagePossibilities [ - ^ rowsPerPagePossibilities -] - -{ #category : #accessing } -MDLSortableTable >> rowsPerPagePossibilities: aCollection [ - rowsPerPagePossibilities := aCollection. - aCollection ifNotEmpty: [ self elementsToShow: aCollection first ] -] - -{ #category : #accessing } -MDLSortableTable >> selectable [ - ^ selectable -] - -{ #category : #accessing } -MDLSortableTable >> selectable: anObject [ - selectable := anObject -] - -{ #category : #testing } -MDLSortableTable >> shouldDisplayPagination [ - ^ self rowsPerPagePossibilities min < rowsCache size -] - -{ #category : #sorting } -MDLSortableTable >> sortAscendingAtRow: aRowIndex [ - self sortAtRow: aRowIndex using: #> -] - -{ #category : #sorting } -MDLSortableTable >> sortAtRow: aRowIndex using: aSelector [ - header - do: [ :each | - (header at: aRowIndex) = each - ifFalse: [ each unsort ] ]. - rows := self rows - sorted: [ :cell :anotherCell | - [ (cell at: aRowIndex) perform: aSelector with: (anotherCell at: aRowIndex) ] - on: MessageNotUnderstood "If the element does not implements the comparators then I should not sort them." - do: [ true ] ] -] - -{ #category : #sorting } -MDLSortableTable >> sortDescendingAtRow: aRowIndex [ - self sortAtRow: aRowIndex using: #< -] - -{ #category : #accessing } -MDLSortableTable >> tableStyle [ - ^ tableStyle -] - -{ #category : #accessing } -MDLSortableTable >> tableStyle: anObject [ - tableStyle := anObject -] - -{ #category : #accessing } -MDLSortableTable >> title [ - ^ title -] - -{ #category : #accessing } -MDLSortableTable >> title: anObject [ - title := anObject -] - -{ #category : #sorting } -MDLSortableTable >> unsort [ - rows := unsortedRows -] +" +Sortable table, renders a table and adds the necessary behavior to navigate trough the table + + Instance Variables + elementsToShow: number of rows that will be rendered + header: a table with the table headers ( auto conversion from object ) + position: the index of the first row to render + rows: a table with all the rows + selectable: a boolean saying that the cells can be selected or not + ajaxOnCompleteHook: a String containing some JS code to be executed after we changed of page. By default it will update the MDL components to initialize the new ones. +" +Class { + #name : #MDLSortableTable, + #superclass : #WAComponent, + #instVars : [ + 'title', + 'header', + 'rows', + 'elementsToShow', + 'unsortedRows', + 'position', + 'rowsPerPagePossibilities', + 'selectable', + 'id', + 'ajaxOnCompleteHook', + 'tableStyle', + 'rowsCache' + ], + #category : #'Material-Design-Lite-Widgets-Table' +} + +{ #category : #accessing } +MDLSortableTable >> ajaxOnCompleteHook [ + "I am a hook to let the user add some javascript after the rendering of a new page. By default I will update the MDL components to initialize the new ones that might be in the table if needed." + + ^ ajaxOnCompleteHook ifNil: [ 'componentHandler.upgradeDom();' ] +] + +{ #category : #accessing } +MDLSortableTable >> ajaxOnCompleteHook: anObject [ + ajaxOnCompleteHook := anObject +] + +{ #category : #javascript } +MDLSortableTable >> ajaxUpdateScriptFrom: html [ + ^ html jQuery + script: [ :s | + s + << + ((html jQuery id: id) load + html: [ :ajaxHtml | self renderTableContentOn: ajaxHtml ]; + onComplete: self ajaxOnCompleteHook) ] +] + +{ #category : #accessing } +MDLSortableTable >> elementsToShow [ + ^ elementsToShow +] + +{ #category : #accessing } +MDLSortableTable >> elementsToShow: anObject [ + elementsToShow := anObject +] + +{ #category : #rendering } +MDLSortableTable >> ensureCurrentPageIsVisible [ + "In some case the elements to show can change. If we currently are in a page that does not exist anymore since the number of elements decreased, we should reset the position." + + self position > rowsCache size + ifTrue: [ self position: 1 ] +] + +{ #category : #accessing } +MDLSortableTable >> header [ + ^ header +] + +{ #category : #accessing } +MDLSortableTable >> header: aCollection [ + header := aCollection collect: [ :each | each asMDLSortableTableHeader ] +] + +{ #category : #rendering } +MDLSortableTable >> indexOfLastRowToShow [ + ^ rowsCache size min: position + elementsToShow - 1 +] + +{ #category : #initialization } +MDLSortableTable >> initialize [ + super initialize. + position := 1. + rows := #(). + header := #(). + unsortedRows := #(). + self rowsPerPagePossibilities: #(10 50 100). + selectable := false +] + +{ #category : #actions } +MDLSortableTable >> nextPosition [ + position + elementsToShow < rowsCache size + ifTrue: [ self position: position + elementsToShow ] +] + +{ #category : #accessing } +MDLSortableTable >> noPagination [ + self rowsPerPagePossibilities: {(Float infinity)} +] + +{ #category : #accessing } +MDLSortableTable >> position [ + ^ position +] + +{ #category : #accessing } +MDLSortableTable >> position: anObject [ + position := anObject +] + +{ #category : #actions } +MDLSortableTable >> previousPosition [ + self position: ((position - elementsToShow) max: 1) +] + +{ #category : #rendering } +MDLSortableTable >> renderButtonTriggering: aMethod withIcon: aSymbol disabled: isDisabled on: html [ + html mdlButton + bePush; + colored; + icon; + disabled: isDisabled; + onClick: [ html jQuery ajax + callback: [ self perform: aMethod ]; + onSuccess: (self ajaxUpdateScriptFrom: html) ] + if: isDisabled not; + with: [ html mdlIcon: aSymbol ] +] + +{ #category : #rendering } +MDLSortableTable >> renderContentOn: html [ + html mdlGrid + class: 'mdl-sorted-table'; + with: [ html mdlCard + shadow: 2; + class: 'mdl-sorted-table__wrapper'; + class: self tableStyle if: self tableStyle isNotNil; + id: (id := html nextId); + with: [ self renderTableContentOn: html ] ] +] + +{ #category : #rendering } +MDLSortableTable >> renderFooterPaginationOn: html [ + html mdlCardTextContainer + class: 'mdl-sorted-table__footer'; + with: [ + html div + mdlTypographyTextRight; + with: [ + html text: 'Rows per page: '. + self renderItemsByPageSelectionComponentOn: html. + self renderPagesInfoOn: html. + self + renderButtonTriggering: #previousPosition + withIcon: #keyboard_arrow_left + disabled: position = 1 + on: html. + self + renderButtonTriggering: #nextPosition + withIcon: #keyboard_arrow_right + disabled: position + elementsToShow > rowsCache size + on: html ] ] +] + +{ #category : #rendering } +MDLSortableTable >> renderHeaderOn: html [ + html + tableHead: [ html tableRow: [ header doWithIndex: [ :head :i | head renderContentOn: html forTable: self columnIndex: i ] ] ] +] + +{ #category : #accessing } +MDLSortableTable >> renderItemsByPageSelectionComponentOn: html [ + html + render: + (MDLSelectWidget new + labelBlock: #asString; + possibilities: rowsPerPagePossibilities; + callback: [ :o | self elementsToShow: o ]; + selectedObject: self elementsToShow; + sortBlock: [ :a :b | a asInteger <= b asInteger ]; + customizationBlock: [ :textField :renderer | textField onChange: (html jQuery ajax serializeThis onComplete: (self ajaxUpdateScriptFrom: html)) ]; + yourself) +] + +{ #category : #rendering } +MDLSortableTable >> renderPagesInfoOn: html [ + html + text: + (String + streamContents: [ :s | + s + print: position; + nextPutAll: ' - '; + print: self indexOfLastRowToShow; + nextPutAll: ' of '; + print: rowsCache size ]) +] + +{ #category : #rendering } +MDLSortableTable >> renderRowContentFor: cells on: html [ + header + doWithIndex: [ :headerCell :columnIndex | + | cell | + (headerCell tableCellOn: html) + with: + ((cell := cells at: columnIndex) isBlock + ifTrue: [ [ cell cull: html ] ] + ifFalse: [ cell ]) ] +] + +{ #category : #rendering } +MDLSortableTable >> renderRowsOn: html [ + ((position to: self indexOfLastRowToShow) collect: [ :rowIndex | rowsCache at: rowIndex ]) + do: [ :cells | html tableRow: [ self renderRowContentFor: cells on: html ] ] +] + +{ #category : #rendering } +MDLSortableTable >> renderTableContentOn: html [ + "We cache the rows because it is possible that the user give a block to execute." + + rowsCache := self rows. + self ensureCurrentPageIsVisible. + html div + class: 'mdl-sorted-table__content'; + with: [ self title ifNotNil: [ :t | html mdlCardTitleContainer: [ html mdlCardTitleText: t level: 2 ] ]. + (selectable + ifTrue: [ html mdlTable selectable ] + ifFalse: [ html mdlTable ]) + with: [ self renderHeaderOn: html. + self renderRowsOn: html ] ]. + self shouldDisplayPagination ifTrue: [ self renderFooterPaginationOn: html ] +] + +{ #category : #accessing } +MDLSortableTable >> rows [ + ^ rows value +] + +{ #category : #accessing } +MDLSortableTable >> rows: anObject [ + rows := anObject. + unsortedRows := anObject +] + +{ #category : #accessing } +MDLSortableTable >> rowsPerPagePossibilities [ + ^ rowsPerPagePossibilities +] + +{ #category : #accessing } +MDLSortableTable >> rowsPerPagePossibilities: aCollection [ + rowsPerPagePossibilities := aCollection. + aCollection ifNotEmpty: [ self elementsToShow: aCollection first ] +] + +{ #category : #accessing } +MDLSortableTable >> selectable [ + ^ selectable +] + +{ #category : #accessing } +MDLSortableTable >> selectable: anObject [ + selectable := anObject +] + +{ #category : #testing } +MDLSortableTable >> shouldDisplayPagination [ + ^ self rowsPerPagePossibilities min < rowsCache size +] + +{ #category : #sorting } +MDLSortableTable >> sortAscendingAtRow: aRowIndex [ + self sortAtRow: aRowIndex using: #> +] + +{ #category : #sorting } +MDLSortableTable >> sortAtRow: aRowIndex using: aSelector [ + header + do: [ :each | + (header at: aRowIndex) = each + ifFalse: [ each unsort ] ]. + rows := self rows + sorted: [ :cell :anotherCell | + [ (cell at: aRowIndex) perform: aSelector with: (anotherCell at: aRowIndex) ] + on: MessageNotUnderstood "If the element does not implements the comparators then I should not sort them." + do: [ true ] ] +] + +{ #category : #sorting } +MDLSortableTable >> sortDescendingAtRow: aRowIndex [ + self sortAtRow: aRowIndex using: #< +] + +{ #category : #accessing } +MDLSortableTable >> tableStyle [ + ^ tableStyle +] + +{ #category : #accessing } +MDLSortableTable >> tableStyle: anObject [ + tableStyle := anObject +] + +{ #category : #accessing } +MDLSortableTable >> title [ + ^ title +] + +{ #category : #accessing } +MDLSortableTable >> title: anObject [ + title := anObject +] + +{ #category : #sorting } +MDLSortableTable >> unsort [ + rows := unsortedRows +] diff --git a/src/Material-Design-Lite-Widgets/MDLSortableTableHeader.class.st b/src/Material-Design-Lite-Widgets/MDLSortableTableHeader.class.st index fea7bd24..735b63a4 100644 --- a/src/Material-Design-Lite-Widgets/MDLSortableTableHeader.class.st +++ b/src/Material-Design-Lite-Widgets/MDLSortableTableHeader.class.st @@ -1,90 +1,90 @@ -Class { - #name : #MDLSortableTableHeader, - #superclass : #Object, - #instVars : [ - 'currentState', - 'unsortedState', - 'cells' - ], - #category : 'Material-Design-Lite-Widgets-Table' -} - -{ #category : #'instance creation' } -MDLSortableTableHeader class >> for: element [ - ^ self new cells: element -] - -{ #category : #converting } -MDLSortableTableHeader >> asMDLSortableTableHeader [ - ^ self -] - -{ #category : #accessing } -MDLSortableTableHeader >> cells [ - ^ cells -] - -{ #category : #accessing } -MDLSortableTableHeader >> cells: aCollection [ - cells := aCollection -] - -{ #category : #accessing } -MDLSortableTableHeader >> currentState [ - ^ currentState - ifNil: [ self unsort. - currentState ] -] - -{ #category : #accessing } -MDLSortableTableHeader >> currentState: anObject [ - currentState := anObject -] - -{ #category : #'state handling' } -MDLSortableTableHeader >> goToNextState [ - self currentState: self currentState nextState -] - -{ #category : #rendering } -MDLSortableTableHeader >> headingCellOn: html [ - ^ html mdlTableHeading - nonNumerical; - style: 'cursor: pointer;'; - yourself -] - -{ #category : #initialization } -MDLSortableTableHeader >> initialize [ - super initialize. - unsortedState := MDLSortableTableHeaderElementUnsorted new -] - -{ #category : #rendering } -MDLSortableTableHeader >> renderContentOn: aRenderer forTable: table columnIndex: i [ - self currentState - renderContentOn: aRenderer - forTable: table - columnIndex: i - header: self -] - -{ #category : #rendering } -MDLSortableTableHeader >> tableCellOn: html [ - ^ html mdlTableCell nonNumerical -] - -{ #category : #sorting } -MDLSortableTableHeader >> unsort [ - self currentState: self unsortedState -] - -{ #category : #accessing } -MDLSortableTableHeader >> unsortedState [ - ^ unsortedState -] - -{ #category : #accessing } -MDLSortableTableHeader >> unsortedState: anObject [ - unsortedState := anObject -] +Class { + #name : #MDLSortableTableHeader, + #superclass : #Object, + #instVars : [ + 'currentState', + 'unsortedState', + 'cells' + ], + #category : 'Material-Design-Lite-Widgets-Table' +} + +{ #category : #'instance creation' } +MDLSortableTableHeader class >> for: element [ + ^ self new cells: element +] + +{ #category : #converting } +MDLSortableTableHeader >> asMDLSortableTableHeader [ + ^ self +] + +{ #category : #accessing } +MDLSortableTableHeader >> cells [ + ^ cells +] + +{ #category : #accessing } +MDLSortableTableHeader >> cells: aCollection [ + cells := aCollection +] + +{ #category : #accessing } +MDLSortableTableHeader >> currentState [ + ^ currentState + ifNil: [ self unsort. + currentState ] +] + +{ #category : #accessing } +MDLSortableTableHeader >> currentState: anObject [ + currentState := anObject +] + +{ #category : #'state handling' } +MDLSortableTableHeader >> goToNextState [ + self currentState: self currentState nextState +] + +{ #category : #rendering } +MDLSortableTableHeader >> headingCellOn: html [ + ^ html mdlTableHeading + nonNumerical; + style: 'cursor: pointer;'; + yourself +] + +{ #category : #initialization } +MDLSortableTableHeader >> initialize [ + super initialize. + unsortedState := MDLSortableTableHeaderElementUnsorted new +] + +{ #category : #rendering } +MDLSortableTableHeader >> renderContentOn: aRenderer forTable: table columnIndex: i [ + self currentState + renderContentOn: aRenderer + forTable: table + columnIndex: i + header: self +] + +{ #category : #rendering } +MDLSortableTableHeader >> tableCellOn: html [ + ^ html mdlTableCell nonNumerical +] + +{ #category : #sorting } +MDLSortableTableHeader >> unsort [ + self currentState: self unsortedState +] + +{ #category : #accessing } +MDLSortableTableHeader >> unsortedState [ + ^ unsortedState +] + +{ #category : #accessing } +MDLSortableTableHeader >> unsortedState: anObject [ + unsortedState := anObject +] diff --git a/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderElementSortedAscending.class.st b/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderElementSortedAscending.class.st index 8e1b16b8..9b1ce380 100644 --- a/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderElementSortedAscending.class.st +++ b/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderElementSortedAscending.class.st @@ -1,22 +1,22 @@ -Class { - #name : #MDLSortableTableHeaderElementSortedAscending, - #superclass : #MDLSortableTableHeaderState, - #category : 'Material-Design-Lite-Widgets-Table' -} - -{ #category : #accessing } -MDLSortableTableHeaderElementSortedAscending class >> defaultNextState [ - ^ MDLSortableTableHeaderElementSortedDescending -] - -{ #category : #rendering } -MDLSortableTableHeaderElementSortedAscending >> renderContentOn: html forTable: table columnIndex: i header: header [ - (header headingCellOn: html) - sortedAscending; - onClick: - (html jQuery ajax - callback: [ table sortDescendingAtRow: i. - header goToNextState ]; - onSuccess: (table ajaxUpdateScriptFrom: html)); - with: header cells -] +Class { + #name : #MDLSortableTableHeaderElementSortedAscending, + #superclass : #MDLSortableTableHeaderState, + #category : 'Material-Design-Lite-Widgets-Table' +} + +{ #category : #accessing } +MDLSortableTableHeaderElementSortedAscending class >> defaultNextState [ + ^ MDLSortableTableHeaderElementSortedDescending +] + +{ #category : #rendering } +MDLSortableTableHeaderElementSortedAscending >> renderContentOn: html forTable: table columnIndex: i header: header [ + (header headingCellOn: html) + sortedAscending; + onClick: + (html jQuery ajax + callback: [ table sortDescendingAtRow: i. + header goToNextState ]; + onSuccess: (table ajaxUpdateScriptFrom: html)); + with: header cells +] diff --git a/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderElementSortedDescending.class.st b/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderElementSortedDescending.class.st index 7fe19f56..8146d05d 100644 --- a/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderElementSortedDescending.class.st +++ b/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderElementSortedDescending.class.st @@ -1,22 +1,22 @@ -Class { - #name : #MDLSortableTableHeaderElementSortedDescending, - #superclass : #MDLSortableTableHeaderState, - #category : 'Material-Design-Lite-Widgets-Table' -} - -{ #category : #accessing } -MDLSortableTableHeaderElementSortedDescending class >> defaultNextState [ - ^ MDLSortableTableHeaderElementUnsorted -] - -{ #category : #rendering } -MDLSortableTableHeaderElementSortedDescending >> renderContentOn: html forTable: table columnIndex: i header: header [ - (header headingCellOn: html) - sortedDescending; - onClick: - (html jQuery ajax - callback: [ table unsort. - header goToNextState ]; - onSuccess: (table ajaxUpdateScriptFrom: html)); - with: header cells -] +Class { + #name : #MDLSortableTableHeaderElementSortedDescending, + #superclass : #MDLSortableTableHeaderState, + #category : 'Material-Design-Lite-Widgets-Table' +} + +{ #category : #accessing } +MDLSortableTableHeaderElementSortedDescending class >> defaultNextState [ + ^ MDLSortableTableHeaderElementUnsorted +] + +{ #category : #rendering } +MDLSortableTableHeaderElementSortedDescending >> renderContentOn: html forTable: table columnIndex: i header: header [ + (header headingCellOn: html) + sortedDescending; + onClick: + (html jQuery ajax + callback: [ table unsort. + header goToNextState ]; + onSuccess: (table ajaxUpdateScriptFrom: html)); + with: header cells +] diff --git a/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderElementUnsorted.class.st b/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderElementUnsorted.class.st index 544cdd73..d869b97f 100644 --- a/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderElementUnsorted.class.st +++ b/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderElementUnsorted.class.st @@ -1,21 +1,21 @@ -Class { - #name : #MDLSortableTableHeaderElementUnsorted, - #superclass : #MDLSortableTableHeaderState, - #category : 'Material-Design-Lite-Widgets-Table' -} - -{ #category : #accessing } -MDLSortableTableHeaderElementUnsorted class >> defaultNextState [ - ^ MDLSortableTableHeaderElementSortedAscending -] - -{ #category : #rendering } -MDLSortableTableHeaderElementUnsorted >> renderContentOn: html forTable: table columnIndex: i header: header [ - (header headingCellOn: html) - onClick: - (html jQuery ajax - callback: [ table sortAscendingAtRow: i. - header goToNextState ]; - onSuccess: (table ajaxUpdateScriptFrom: html)); - with: header cells -] +Class { + #name : #MDLSortableTableHeaderElementUnsorted, + #superclass : #MDLSortableTableHeaderState, + #category : 'Material-Design-Lite-Widgets-Table' +} + +{ #category : #accessing } +MDLSortableTableHeaderElementUnsorted class >> defaultNextState [ + ^ MDLSortableTableHeaderElementSortedAscending +] + +{ #category : #rendering } +MDLSortableTableHeaderElementUnsorted >> renderContentOn: html forTable: table columnIndex: i header: header [ + (header headingCellOn: html) + onClick: + (html jQuery ajax + callback: [ table sortAscendingAtRow: i. + header goToNextState ]; + onSuccess: (table ajaxUpdateScriptFrom: html)); + with: header cells +] diff --git a/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderNumeric.class.st b/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderNumeric.class.st index f4e367a9..e9098bd2 100644 --- a/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderNumeric.class.st +++ b/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderNumeric.class.st @@ -1,17 +1,17 @@ -Class { - #name : #MDLSortableTableHeaderNumeric, - #superclass : #MDLSortableTableHeader, - #category : 'Material-Design-Lite-Widgets-Table' -} - -{ #category : #rendering } -MDLSortableTableHeaderNumeric >> headingCellOn: html [ - ^ html mdlTableHeading - style: 'cursor: pointer;'; - yourself -] - -{ #category : #rendering } -MDLSortableTableHeaderNumeric >> tableCellOn: html [ - ^ html mdlTableCell -] +Class { + #name : #MDLSortableTableHeaderNumeric, + #superclass : #MDLSortableTableHeader, + #category : 'Material-Design-Lite-Widgets-Table' +} + +{ #category : #rendering } +MDLSortableTableHeaderNumeric >> headingCellOn: html [ + ^ html mdlTableHeading + style: 'cursor: pointer;'; + yourself +] + +{ #category : #rendering } +MDLSortableTableHeaderNumeric >> tableCellOn: html [ + ^ html mdlTableCell +] diff --git a/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderState.class.st b/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderState.class.st index 5f59c824..e4245997 100644 --- a/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderState.class.st +++ b/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderState.class.st @@ -1,43 +1,43 @@ -Class { - #name : #MDLSortableTableHeaderState, - #superclass : #Object, - #instVars : [ - 'nextState' - ], - #category : 'Material-Design-Lite-Widgets-Table' -} - -{ #category : #accessing } -MDLSortableTableHeaderState class >> defaultNextState [ - ^ self subclassResponsibility -] - -{ #category : #'instance creation' } -MDLSortableTableHeaderState class >> for: element [ - ^ self new element: element -] - -{ #category : #accessing } -MDLSortableTableHeaderState >> defaultNextState [ - ^ self class defaultNextState -] - -{ #category : #initialization } -MDLSortableTableHeaderState >> initializeNextState [ - self nextState: (self defaultNextState new nextState: (self defaultNextState defaultNextState new nextState: self)) -] - -{ #category : #accessing } -MDLSortableTableHeaderState >> nextState [ - ^ nextState ifNil: [ self initializeNextState. nextState ] -] - -{ #category : #accessing } -MDLSortableTableHeaderState >> nextState: anObject [ - nextState := anObject -] - -{ #category : #rendering } -MDLSortableTableHeaderState >> renderContentOn: html forTable: table columnIndex: i header: header [ - self subclassResponsibility -] +Class { + #name : #MDLSortableTableHeaderState, + #superclass : #Object, + #instVars : [ + 'nextState' + ], + #category : 'Material-Design-Lite-Widgets-Table' +} + +{ #category : #accessing } +MDLSortableTableHeaderState class >> defaultNextState [ + ^ self subclassResponsibility +] + +{ #category : #'instance creation' } +MDLSortableTableHeaderState class >> for: element [ + ^ self new element: element +] + +{ #category : #accessing } +MDLSortableTableHeaderState >> defaultNextState [ + ^ self class defaultNextState +] + +{ #category : #initialization } +MDLSortableTableHeaderState >> initializeNextState [ + self nextState: (self defaultNextState new nextState: (self defaultNextState defaultNextState new nextState: self)) +] + +{ #category : #accessing } +MDLSortableTableHeaderState >> nextState [ + ^ nextState ifNil: [ self initializeNextState. nextState ] +] + +{ #category : #accessing } +MDLSortableTableHeaderState >> nextState: anObject [ + nextState := anObject +] + +{ #category : #rendering } +MDLSortableTableHeaderState >> renderContentOn: html forTable: table columnIndex: i header: header [ + self subclassResponsibility +] diff --git a/src/Material-Design-Lite-Widgets/MDLStringColumnDescription.class.st b/src/Material-Design-Lite-Widgets/MDLStringColumnDescription.class.st index 6ac6e50c..3ec0d0bf 100644 --- a/src/Material-Design-Lite-Widgets/MDLStringColumnDescription.class.st +++ b/src/Material-Design-Lite-Widgets/MDLStringColumnDescription.class.st @@ -1,27 +1,27 @@ -" -I model a string column. - -My values are of kind string. Because of that, I align the title of the column on the left side. -" -Class { - #name : #MDLStringColumnDescription, - #superclass : #MDLTableColumnDescription, - #category : #'Material-Design-Lite-Widgets-Table' -} - -{ #category : #rendering } -MDLStringColumnDescription >> render: row on: html [ - html mdlTableCell - id: (self generateIdUsing: html); - class: 'mdl-table-widget__cell--string'; - nonNumerical; - with: (self evaluation value: row) -] - -{ #category : #rendering } -MDLStringColumnDescription >> renderHeadingOn: html [ - (super renderHeadingOn: html) - class: 'mdl-table-widget__cell--string'; - nonNumerical; - with: self title. -] +" +I model a string column. + +My values are of kind string. Because of that, I align the title of the column on the left side. +" +Class { + #name : #MDLStringColumnDescription, + #superclass : #MDLTableColumnDescription, + #category : #'Material-Design-Lite-Widgets-Table' +} + +{ #category : #rendering } +MDLStringColumnDescription >> render: row on: html [ + html mdlTableCell + id: (self generateIdUsing: html); + class: 'mdl-table-widget__cell--string'; + nonNumerical; + with: (self evaluation value: row) +] + +{ #category : #rendering } +MDLStringColumnDescription >> renderHeadingOn: html [ + (super renderHeadingOn: html) + class: 'mdl-table-widget__cell--string'; + nonNumerical; + with: self title. +] diff --git a/src/Material-Design-Lite-Widgets/MDLSubstringFilter.class.st b/src/Material-Design-Lite-Widgets/MDLSubstringFilter.class.st index ae38a5f9..67d1da12 100644 --- a/src/Material-Design-Lite-Widgets/MDLSubstringFilter.class.st +++ b/src/Material-Design-Lite-Widgets/MDLSubstringFilter.class.st @@ -1,13 +1,13 @@ -" -I am a nested list filter keeping only elements whose name includes the pattern passed by the user. -" -Class { - #name : #MDLSubstringFilter, - #superclass : #MDLAbstractFilter, - #category : 'Material-Design-Lite-Widgets-List' -} - -{ #category : #accessing } -MDLSubstringFilter class >> formatedElement: aString matches: aPattern [ - ^ aString includesSubstring: aPattern -] +" +I am a nested list filter keeping only elements whose name includes the pattern passed by the user. +" +Class { + #name : #MDLSubstringFilter, + #superclass : #MDLAbstractFilter, + #category : 'Material-Design-Lite-Widgets-List' +} + +{ #category : #accessing } +MDLSubstringFilter class >> formatedElement: aString matches: aPattern [ + ^ aString includesSubstring: aPattern +] diff --git a/src/Material-Design-Lite-Widgets/MDLSwitchWidget.class.st b/src/Material-Design-Lite-Widgets/MDLSwitchWidget.class.st index 32fef9b6..24c05a76 100644 --- a/src/Material-Design-Lite-Widgets/MDLSwitchWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLSwitchWidget.class.st @@ -1,17 +1,17 @@ -Class { - #name : #MDLSwitchWidget, - #superclass : #MDLWidget, - #category : 'Material-Design-Lite-Widgets' -} - -{ #category : #rendering } -MDLSwitchWidget >> renderContentOn: html [ - html div - style: 'width: 28px;'; - with: [ - html mdlSwitchContainer for: (self id); with: [ - html mdlSwitch id: (self id); value: self value. - html mdlSwitchLabel - ] - ] -] +Class { + #name : #MDLSwitchWidget, + #superclass : #MDLWidget, + #category : 'Material-Design-Lite-Widgets' +} + +{ #category : #rendering } +MDLSwitchWidget >> renderContentOn: html [ + html div + style: 'width: 28px;'; + with: [ + html mdlSwitchContainer for: (self id); with: [ + html mdlSwitch id: (self id); value: self value. + html mdlSwitchLabel + ] + ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLTabWidget.class.st b/src/Material-Design-Lite-Widgets/MDLTabWidget.class.st index 2bcc12ed..9ae01028 100644 --- a/src/Material-Design-Lite-Widgets/MDLTabWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLTabWidget.class.st @@ -1,44 +1,62 @@ -" -I represent a simple widget to use mdlTable -" -Class { - #name : #MDLTabWidget, - #superclass : #MDLHighLevelWidget, - #instVars : [ - 'tabs' - ], - #category : 'Material-Design-Lite-Widgets-Tab' -} - -{ #category : #adding } -MDLTabWidget >> addTabNamed: aString content: anObject [ - tabs at: aString put: anObject -] - -{ #category : #initialization } -MDLTabWidget >> initialize [ - super initialize. - tabs := OrderedDictionary new -] - -{ #category : #rendering } -MDLTabWidget >> renderContentOn: html [ - self ensureId: html. - html mdlTabs - id: self id; - with: [ | tabIds | - tabIds := Dictionary new. - html - mdlTabBar: [ tabs - keysAndValuesDo: [ :label :tabContent | - html mdlTab - url: '#' , (tabIds at: tabContent ifAbsentPut: [ html nextId ]); - isActiveIf: (tabs indexOfKey: label) = 1; - with: label ] ]. - tabs - keysAndValuesDo: [ :label :tabContent | - html mdlTabsPanel - id: (tabIds at: tabContent); - isActiveIf: (tabs indexOfKey: label) = 1; - with: tabContent ] ] -] +" +I represent a simple widget to use mdlTable +" +Class { + #name : #MDLTabWidget, + #superclass : #MDLHighLevelWidget, + #instVars : [ + 'tabs', + 'selectedTabIndex' + ], + #category : #'Material-Design-Lite-Widgets-Tab' +} + +{ #category : #adding } +MDLTabWidget >> addTabNamed: aString content: anObject [ + tabs at: aString put: anObject +] + +{ #category : #initialization } +MDLTabWidget >> initialize [ + super initialize. + tabs := OrderedDictionary new. + selectedTabIndex := 1 +] + +{ #category : #rendering } +MDLTabWidget >> renderContentOn: html [ + +self ensureId: html. + html mdlTabs + id: self id; + with: [ + | tabIds | + tabIds := Dictionary new. + html mdlTabBar: [ + tabs keysAndValuesDo: [ :label :tabContent | + html mdlTab + url: + '#' , (tabIds at: tabContent ifAbsentPut: [ html nextId ]); + + onClick: (html jQuery ajax callback: [ + self selectedTabIndex: (tabs indexOfKey: label) ]); + isActiveIf: (tabs indexOfKey: label) = self selectedTabIndex; + with: label ] ]. + tabs keysAndValuesDo: [ :label :tabContent | + html mdlTabsPanel + id: (tabIds at: tabContent); + isActiveIf: (tabs indexOfKey: label) = self selectedTabIndex; + with: tabContent ] ] +] + +{ #category : #accessing } +MDLTabWidget >> selectedTabIndex [ + + ^selectedTabIndex +] + +{ #category : #accessing } +MDLTabWidget >> selectedTabIndex: aNumber [ + + selectedTabIndex := aNumber +] diff --git a/src/Material-Design-Lite-Widgets/MDLTableColumnDescription.class.st b/src/Material-Design-Lite-Widgets/MDLTableColumnDescription.class.st index ee4b2aa2..9fa437ea 100644 --- a/src/Material-Design-Lite-Widgets/MDLTableColumnDescription.class.st +++ b/src/Material-Design-Lite-Widgets/MDLTableColumnDescription.class.st @@ -1,76 +1,76 @@ -" -I am an abstract super class to model the description of a column for a MDLTableWidget. - -I hold my: -- #title which is the string to display as column name -- #idBlock which is the block that I use to generate an id. This block takes an argument which is the html canvas. -- #evaluation which is the block that I use to get the content of a cell concerning myself by providing it a row object. - -My subclasses model concrete column description check them for concrete examples. -" -Class { - #name : #MDLTableColumnDescription, - #superclass : #Object, - #instVars : [ - 'title', - 'evaluation', - 'idBlock' - ], - #category : #'Material-Design-Lite-Widgets-Table' -} - -{ #category : #accessing } -MDLTableColumnDescription >> evaluation [ - ^ evaluation -] - -{ #category : #accessing } -MDLTableColumnDescription >> evaluation: anObject [ - evaluation := anObject -] - -{ #category : #private } -MDLTableColumnDescription >> generateIdUsing: html [ - ^ self idBlock cull: html -] - -{ #category : #accessing } -MDLTableColumnDescription >> idBlock [ - ^ idBlock -] - -{ #category : #accessing } -MDLTableColumnDescription >> idBlock: anObject [ - idBlock := anObject -] - -{ #category : #initialization } -MDLTableColumnDescription >> initialize [ - super initialize. - self idBlock: [ :html | html nextId ] -] - -{ #category : #rendering } -MDLTableColumnDescription >> render: row on: html [ - self subclassResponsibility -] - -{ #category : #rendering } -MDLTableColumnDescription >> renderHeadingOn: html [ - | heading | - heading := html mdlTableHeading - id: (self generateIdUsing: html); - yourself. - - ^ heading -] - -{ #category : #accessing } -MDLTableColumnDescription >> title [ - ^ title -] - -{ #category : #accessing } -MDLTableColumnDescription >> title: anObject [ - title := anObject -] +" +I am an abstract super class to model the description of a column for a MDLTableWidget. + +I hold my: +- #title which is the string to display as column name +- #idBlock which is the block that I use to generate an id. This block takes an argument which is the html canvas. +- #evaluation which is the block that I use to get the content of a cell concerning myself by providing it a row object. + +My subclasses model concrete column description check them for concrete examples. +" +Class { + #name : #MDLTableColumnDescription, + #superclass : #Object, + #instVars : [ + 'title', + 'evaluation', + 'idBlock' + ], + #category : #'Material-Design-Lite-Widgets-Table' +} + +{ #category : #accessing } +MDLTableColumnDescription >> evaluation [ + ^ evaluation +] + +{ #category : #accessing } +MDLTableColumnDescription >> evaluation: anObject [ + evaluation := anObject +] + +{ #category : #private } +MDLTableColumnDescription >> generateIdUsing: html [ + ^ self idBlock cull: html +] + +{ #category : #accessing } +MDLTableColumnDescription >> idBlock [ + ^ idBlock +] + +{ #category : #accessing } +MDLTableColumnDescription >> idBlock: anObject [ + idBlock := anObject +] + +{ #category : #initialization } +MDLTableColumnDescription >> initialize [ + super initialize. + self idBlock: [ :html | html nextId ] +] + +{ #category : #rendering } +MDLTableColumnDescription >> render: row on: html [ + self subclassResponsibility +] + +{ #category : #rendering } +MDLTableColumnDescription >> renderHeadingOn: html [ + | heading | + heading := html mdlTableHeading + id: (self generateIdUsing: html); + yourself. + + ^ heading +] + +{ #category : #accessing } +MDLTableColumnDescription >> title [ + ^ title +] + +{ #category : #accessing } +MDLTableColumnDescription >> title: anObject [ + title := anObject +] diff --git a/src/Material-Design-Lite-Widgets/MDLTableWidget.class.st b/src/Material-Design-Lite-Widgets/MDLTableWidget.class.st index e98d4238..4aaa0ea9 100644 --- a/src/Material-Design-Lite-Widgets/MDLTableWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLTableWidget.class.st @@ -1,124 +1,124 @@ -" -I am table widget which aims to provide a high-level API to generate MDL tables. - -I work by providing myself a #collection which just needs to be iterable (i.e. understand #do:) and a list of column descriptions. - -I provide a nice API to add colum descriptions (see my 'adding' protocol). -" -Class { - #name : #MDLTableWidget, - #superclass : #WAComponent, - #instVars : [ - 'columnDescriptions', - 'collection' - ], - #category : #'Material-Design-Lite-Widgets-Table' -} - -{ #category : #adding } -MDLTableWidget >> addAjaxButtonColumnNamed: aString iconName: iconName onClick: onClickBlock [ - self addAjaxButtonColumnNamed: aString iconName: iconName onClick: onClickBlock tooltip: nil -] - -{ #category : #adding } -MDLTableWidget >> addAjaxButtonColumnNamed: aString iconName: iconName onClick: onClickBlock tooltip: tooltip [ - self addColumn: (MDLAjaxButtonColumnDescription new - title: aString; - iconName: iconName; - onClickBlock: onClickBlock; - tooltip: tooltip; - yourself) -] - -{ #category : #adding } -MDLTableWidget >> addAjaxButtonColumnWithIconName: iconName onClick: onClickBlock tooltip: tooltip [ - self addAjaxButtonColumnNamed: '' iconName: iconName onClick: onClickBlock tooltip: tooltip -] - -{ #category : #adding } -MDLTableWidget >> addButtonColumnNamed: aString iconName: iconName onClick: onClickBlock tooltip: tooltip [ - self addColumn: (MDLButtonColumnDescription new - title: aString; - iconName: iconName; - onClickBlock: onClickBlock; - tooltip: tooltip; - yourself) -] - -{ #category : #adding } -MDLTableWidget >> addButtonColumnWithIconName: iconName onClick: onClickBlock tooltip: tooltip [ - self addButtonColumnNamed: '' iconName: iconName onClick: onClickBlock tooltip: tooltip -] - -{ #category : #adding } -MDLTableWidget >> addColumn: aColumnDescription [ - columnDescriptions add: aColumnDescription -] - -{ #category : #adding } -MDLTableWidget >> addNumericColumnNamed: aString evaluated: aBlock [ - self addColumn: (MDLNumericColumnDescription new - title: aString; - evaluation: aBlock; - yourself) -] - -{ #category : #adding } -MDLTableWidget >> addStringColumnNamed: aString evaluated: aBlock [ - self addColumn: (MDLStringColumnDescription new - title: aString; - evaluation: aBlock; - yourself) -] - -{ #category : #accessing } -MDLTableWidget >> collection [ - ^ collection -] - -{ #category : #accessing } -MDLTableWidget >> collection: anObject [ - collection := anObject -] - -{ #category : #accessing } -MDLTableWidget >> columnDescriptions [ - ^ columnDescriptions -] - -{ #category : #initialization } -MDLTableWidget >> initialize [ - super initialize. - columnDescriptions := OrderedCollection new. - collection := #() -] - -{ #category : #rendering } -MDLTableWidget >> renderContentOn: html [ - html mdlTable - class: 'mdl-table-widget'; - with: [ - self renderTableHeadOn: html. - self renderTableBodyOn: html ] -] - -{ #category : #rendering } -MDLTableWidget >> renderTableBodyOn: html [ - html tableBody - class: 'mdl-table-widget__body'; - with: [ - self collection do: [ :row | - html tableRow: [ - self columnDescriptions do: [ :columnDescription | - columnDescription render: row on: html ] ] ] ] -] - -{ #category : #rendering } -MDLTableWidget >> renderTableHeadOn: html [ - html tableHead - class: 'mdl-table-widget__head'; - with: [ - html tableRow: [ - self columnDescriptions do: [ :column | - column renderHeadingOn: html ] ] ] -] +" +I am table widget which aims to provide a high-level API to generate MDL tables. + +I work by providing myself a #collection which just needs to be iterable (i.e. understand #do:) and a list of column descriptions. + +I provide a nice API to add colum descriptions (see my 'adding' protocol). +" +Class { + #name : #MDLTableWidget, + #superclass : #WAComponent, + #instVars : [ + 'columnDescriptions', + 'collection' + ], + #category : #'Material-Design-Lite-Widgets-Table' +} + +{ #category : #adding } +MDLTableWidget >> addAjaxButtonColumnNamed: aString iconName: iconName onClick: onClickBlock [ + self addAjaxButtonColumnNamed: aString iconName: iconName onClick: onClickBlock tooltip: nil +] + +{ #category : #adding } +MDLTableWidget >> addAjaxButtonColumnNamed: aString iconName: iconName onClick: onClickBlock tooltip: tooltip [ + self addColumn: (MDLAjaxButtonColumnDescription new + title: aString; + iconName: iconName; + onClickBlock: onClickBlock; + tooltip: tooltip; + yourself) +] + +{ #category : #adding } +MDLTableWidget >> addAjaxButtonColumnWithIconName: iconName onClick: onClickBlock tooltip: tooltip [ + self addAjaxButtonColumnNamed: '' iconName: iconName onClick: onClickBlock tooltip: tooltip +] + +{ #category : #adding } +MDLTableWidget >> addButtonColumnNamed: aString iconName: iconName onClick: onClickBlock tooltip: tooltip [ + self addColumn: (MDLButtonColumnDescription new + title: aString; + iconName: iconName; + onClickBlock: onClickBlock; + tooltip: tooltip; + yourself) +] + +{ #category : #adding } +MDLTableWidget >> addButtonColumnWithIconName: iconName onClick: onClickBlock tooltip: tooltip [ + self addButtonColumnNamed: '' iconName: iconName onClick: onClickBlock tooltip: tooltip +] + +{ #category : #adding } +MDLTableWidget >> addColumn: aColumnDescription [ + columnDescriptions add: aColumnDescription +] + +{ #category : #adding } +MDLTableWidget >> addNumericColumnNamed: aString evaluated: aBlock [ + self addColumn: (MDLNumericColumnDescription new + title: aString; + evaluation: aBlock; + yourself) +] + +{ #category : #adding } +MDLTableWidget >> addStringColumnNamed: aString evaluated: aBlock [ + self addColumn: (MDLStringColumnDescription new + title: aString; + evaluation: aBlock; + yourself) +] + +{ #category : #accessing } +MDLTableWidget >> collection [ + ^ collection +] + +{ #category : #accessing } +MDLTableWidget >> collection: anObject [ + collection := anObject +] + +{ #category : #accessing } +MDLTableWidget >> columnDescriptions [ + ^ columnDescriptions +] + +{ #category : #initialization } +MDLTableWidget >> initialize [ + super initialize. + columnDescriptions := OrderedCollection new. + collection := #() +] + +{ #category : #rendering } +MDLTableWidget >> renderContentOn: html [ + html mdlTable + class: 'mdl-table-widget'; + with: [ + self renderTableHeadOn: html. + self renderTableBodyOn: html ] +] + +{ #category : #rendering } +MDLTableWidget >> renderTableBodyOn: html [ + html tableBody + class: 'mdl-table-widget__body'; + with: [ + self collection do: [ :row | + html tableRow: [ + self columnDescriptions do: [ :columnDescription | + columnDescription render: row on: html ] ] ] ] +] + +{ #category : #rendering } +MDLTableWidget >> renderTableHeadOn: html [ + html tableHead + class: 'mdl-table-widget__head'; + with: [ + html tableRow: [ + self columnDescriptions do: [ :column | + column renderHeadingOn: html ] ] ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLTextAreaWidget.class.st b/src/Material-Design-Lite-Widgets/MDLTextAreaWidget.class.st index 8a1efc35..c36932a9 100644 --- a/src/Material-Design-Lite-Widgets/MDLTextAreaWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLTextAreaWidget.class.st @@ -1,25 +1,25 @@ -" -I represent a text area with material design style. -You can use all methods of MDLTextFieldWidget on me. -" -Class { - #name : #MDLTextAreaWidget, - #superclass : #MDLTextFieldWidget, - #category : #'Material-Design-Lite-Widgets-Form' -} - -{ #category : #options } -MDLTextAreaWidget >> columns: aNumber [ - self propertiesAt: #columns: put: (Array with: aNumber) -] - -{ #category : #initialization } -MDLTextAreaWidget >> initialize [ - super initialize. - brush := MDLTextArea new -] - -{ #category : #options } -MDLTextAreaWidget >> rows: aNumber [ - self propertiesAt: #rows: put: (Array with: aNumber) -] +" +I represent a text area with material design style. +You can use all methods of MDLTextFieldWidget on me. +" +Class { + #name : #MDLTextAreaWidget, + #superclass : #MDLTextFieldWidget, + #category : #'Material-Design-Lite-Widgets-Form' +} + +{ #category : #options } +MDLTextAreaWidget >> columns: aNumber [ + self propertiesAt: #columns: put: (Array with: aNumber) +] + +{ #category : #initialization } +MDLTextAreaWidget >> initialize [ + super initialize. + brush := MDLTextArea new +] + +{ #category : #options } +MDLTextAreaWidget >> rows: aNumber [ + self propertiesAt: #rows: put: (Array with: aNumber) +] diff --git a/src/Material-Design-Lite-Widgets/MDLTextFieldWidget.class.st b/src/Material-Design-Lite-Widgets/MDLTextFieldWidget.class.st index d492734f..33cc4b4b 100644 --- a/src/Material-Design-Lite-Widgets/MDLTextFieldWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLTextFieldWidget.class.st @@ -1,189 +1,189 @@ -" -I represent a text input field widget -" -Class { - #name : #MDLTextFieldWidget, - #superclass : #MDLHighLevelWidget, - #instVars : [ - 'label', - 'brush', - 'isExpandable', - 'isFloatingLabel', - 'patternErrorMessage', - 'errorMessage' - ], - #category : 'Material-Design-Lite-Widgets-Form' -} - -{ #category : #'instance creation' } -MDLTextFieldWidget class >> labeled: aString callback: aBlock [ - ^ self labeled: aString callback: aBlock floatingLabel: false -] - -{ #category : #'instance creation' } -MDLTextFieldWidget class >> labeled: aString callback: aBlock floatingLabel: aBoolean [ - ^ self - labeled: aString - callback: aBlock - floatingLabel: aBoolean - expandable: false -] - -{ #category : #'instance creation' } -MDLTextFieldWidget class >> labeled: aString callback: aBlock floatingLabel: aBoolean expandable: aBoolean2 [ - ^ self new - label: aString; - callback: aBlock; - floatingLabelIf: aBoolean; - expandableIf: aBoolean2; - yourself -] - -{ #category : #options } -MDLTextFieldWidget >> beExpandable [ - isExpandable := true -] - -{ #category : #options } -MDLTextFieldWidget >> beFloatingLabel [ - isFloatingLabel := true -] - -{ #category : #options } -MDLTextFieldWidget >> callback: aBlock [ - self propertiesAt: #callback: put: (Array with: aBlock) -] - -{ #category : #accessing } -MDLTextFieldWidget >> errorMessage [ - ^ errorMessage ifNil: [ errorMessage := '' ] -] - -{ #category : #accessing } -MDLTextFieldWidget >> errorMessage: aString [ - errorMessage := aString -] - -{ #category : #accessing } -MDLTextFieldWidget >> errorMessage: aString if: aBoolean [ - aBoolean - ifTrue: [ errorMessage := aString ] -] - -{ #category : #options } -MDLTextFieldWidget >> expandableIf: aBoolean [ - aBoolean - ifTrue: [ self beExpandable ] -] - -{ #category : #options } -MDLTextFieldWidget >> floatingLabelIf: aBoolean [ - aBoolean - ifTrue: [ self beFloatingLabel ] -] - -{ #category : #initialization } -MDLTextFieldWidget >> initialize [ - super initialize. - brush := MDLTextFieldInput new. - isExpandable := false. - isFloatingLabel := false. - patternErrorMessage := '' -] - -{ #category : #accessing } -MDLTextFieldWidget >> label [ - ^ label -] - -{ #category : #accessing } -MDLTextFieldWidget >> label: aString [ - label := aString -] - -{ #category : #options } -MDLTextFieldWidget >> on: aSymbol of: anObject [ - self propertiesAt: #on:of: put: (Array with: aSymbol with: anObject) -] - -{ #category : #options } -MDLTextFieldWidget >> onChange: anObject [ - self propertiesAt: #onChange: put: (Array with: anObject) -] - -{ #category : #options } -MDLTextFieldWidget >> onEnter: anObject [ - self propertiesAt: #onEnter: put: (Array with: anObject) -] - -{ #category : #options } -MDLTextFieldWidget >> onKeyUp: anObject [ - self propertiesAt: #onKeyUp: put: (Array with: anObject) -] - -{ #category : #options } -MDLTextFieldWidget >> onSubmit: anObject [ - self propertiesAt: #onSubmit: put: (Array with: anObject) -] - -{ #category : #options } -MDLTextFieldWidget >> pattern: anObject [ - self propertiesAt: #pattern: put: (Array with: anObject) -] - -{ #category : #options } -MDLTextFieldWidget >> pattern: aPattern errorMessage: aString [ - "patternsDictionary at: anObject put: aString" - - self pattern: aPattern. - patternErrorMessage := aString -] - -{ #category : #options } -MDLTextFieldWidget >> readonly: aBoolean [ - self propertiesAt: #readonly: put: (Array with: aBoolean) -] - -{ #category : #rendering } -MDLTextFieldWidget >> renderContentOn: html [ - | inputId | - self id ifNotNil: [ :aString | inputId := aString ] ifNil: [ inputId := html nextId ]. - html mdlTextFieldContainer - class: (self properties at: #class: ifAbsent: [ '' ]); - beFloatingLabelIf: isFloatingLabel; - beExpandableIf: isExpandable; - with: [ - label - ifNotNil: [ - html mdlTextFieldLabel - for: inputId; - with: label ]. - html - brush: - (brush - id: inputId; - yourself). - self addPropertiesToBrush: brush. - patternErrorMessage ifNotEmpty: [ html mdlTextFieldError: patternErrorMessage ]. - self errorMessage ifNotEmpty: [ :message | html mdlTextFieldError: message ] ] -] - -{ #category : #options } -MDLTextFieldWidget >> required [ - self propertiesAt: #required put: Array new -] - -{ #category : #options } -MDLTextFieldWidget >> size: anObject [ - self propertiesAt: #size: put: (Array with: anObject) -] - -{ #category : #options } -MDLTextFieldWidget >> type: anObject [ - self propertiesAt: #type: put: (Array with: anObject) -] - -{ #category : #options } -MDLTextFieldWidget >> value: anObject [ - self propertiesAt: #value: put: (Array with: anObject) -] +" +I represent a text input field widget +" +Class { + #name : #MDLTextFieldWidget, + #superclass : #MDLHighLevelWidget, + #instVars : [ + 'label', + 'brush', + 'isExpandable', + 'isFloatingLabel', + 'patternErrorMessage', + 'errorMessage' + ], + #category : 'Material-Design-Lite-Widgets-Form' +} + +{ #category : #'instance creation' } +MDLTextFieldWidget class >> labeled: aString callback: aBlock [ + ^ self labeled: aString callback: aBlock floatingLabel: false +] + +{ #category : #'instance creation' } +MDLTextFieldWidget class >> labeled: aString callback: aBlock floatingLabel: aBoolean [ + ^ self + labeled: aString + callback: aBlock + floatingLabel: aBoolean + expandable: false +] + +{ #category : #'instance creation' } +MDLTextFieldWidget class >> labeled: aString callback: aBlock floatingLabel: aBoolean expandable: aBoolean2 [ + ^ self new + label: aString; + callback: aBlock; + floatingLabelIf: aBoolean; + expandableIf: aBoolean2; + yourself +] + +{ #category : #options } +MDLTextFieldWidget >> beExpandable [ + isExpandable := true +] + +{ #category : #options } +MDLTextFieldWidget >> beFloatingLabel [ + isFloatingLabel := true +] + +{ #category : #options } +MDLTextFieldWidget >> callback: aBlock [ + self propertiesAt: #callback: put: (Array with: aBlock) +] + +{ #category : #accessing } +MDLTextFieldWidget >> errorMessage [ + ^ errorMessage ifNil: [ errorMessage := '' ] +] + +{ #category : #accessing } +MDLTextFieldWidget >> errorMessage: aString [ + errorMessage := aString +] + +{ #category : #accessing } +MDLTextFieldWidget >> errorMessage: aString if: aBoolean [ + aBoolean + ifTrue: [ errorMessage := aString ] +] + +{ #category : #options } +MDLTextFieldWidget >> expandableIf: aBoolean [ + aBoolean + ifTrue: [ self beExpandable ] +] + +{ #category : #options } +MDLTextFieldWidget >> floatingLabelIf: aBoolean [ + aBoolean + ifTrue: [ self beFloatingLabel ] +] + +{ #category : #initialization } +MDLTextFieldWidget >> initialize [ + super initialize. + brush := MDLTextFieldInput new. + isExpandable := false. + isFloatingLabel := false. + patternErrorMessage := '' +] + +{ #category : #accessing } +MDLTextFieldWidget >> label [ + ^ label +] + +{ #category : #accessing } +MDLTextFieldWidget >> label: aString [ + label := aString +] + +{ #category : #options } +MDLTextFieldWidget >> on: aSymbol of: anObject [ + self propertiesAt: #on:of: put: (Array with: aSymbol with: anObject) +] + +{ #category : #options } +MDLTextFieldWidget >> onChange: anObject [ + self propertiesAt: #onChange: put: (Array with: anObject) +] + +{ #category : #options } +MDLTextFieldWidget >> onEnter: anObject [ + self propertiesAt: #onEnter: put: (Array with: anObject) +] + +{ #category : #options } +MDLTextFieldWidget >> onKeyUp: anObject [ + self propertiesAt: #onKeyUp: put: (Array with: anObject) +] + +{ #category : #options } +MDLTextFieldWidget >> onSubmit: anObject [ + self propertiesAt: #onSubmit: put: (Array with: anObject) +] + +{ #category : #options } +MDLTextFieldWidget >> pattern: anObject [ + self propertiesAt: #pattern: put: (Array with: anObject) +] + +{ #category : #options } +MDLTextFieldWidget >> pattern: aPattern errorMessage: aString [ + "patternsDictionary at: anObject put: aString" + + self pattern: aPattern. + patternErrorMessage := aString +] + +{ #category : #options } +MDLTextFieldWidget >> readonly: aBoolean [ + self propertiesAt: #readonly: put: (Array with: aBoolean) +] + +{ #category : #rendering } +MDLTextFieldWidget >> renderContentOn: html [ + | inputId | + self id ifNotNil: [ :aString | inputId := aString ] ifNil: [ inputId := html nextId ]. + html mdlTextFieldContainer + class: (self properties at: #class: ifAbsent: [ '' ]); + beFloatingLabelIf: isFloatingLabel; + beExpandableIf: isExpandable; + with: [ + label + ifNotNil: [ + html mdlTextFieldLabel + for: inputId; + with: label ]. + html + brush: + (brush + id: inputId; + yourself). + self addPropertiesToBrush: brush. + patternErrorMessage ifNotEmpty: [ html mdlTextFieldError: patternErrorMessage ]. + self errorMessage ifNotEmpty: [ :message | html mdlTextFieldError: message ] ] +] + +{ #category : #options } +MDLTextFieldWidget >> required [ + self propertiesAt: #required put: Array new +] + +{ #category : #options } +MDLTextFieldWidget >> size: anObject [ + self propertiesAt: #size: put: (Array with: anObject) +] + +{ #category : #options } +MDLTextFieldWidget >> type: anObject [ + self propertiesAt: #type: put: (Array with: anObject) +] + +{ #category : #options } +MDLTextFieldWidget >> value: anObject [ + self propertiesAt: #value: put: (Array with: anObject) +] diff --git a/src/Material-Design-Lite-Widgets/MDLWidget.class.st b/src/Material-Design-Lite-Widgets/MDLWidget.class.st index 4e1bf978..038db440 100644 --- a/src/Material-Design-Lite-Widgets/MDLWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLWidget.class.st @@ -1,55 +1,55 @@ -Class { - #name : #MDLWidget, - #superclass : #WAComponent, - #instVars : [ - 'id', - 'value' - ], - #category : 'Material-Design-Lite-Widgets' -} - -{ #category : #initialize } -MDLWidget class >> id: aStringID [ - ^self id: aStringID value: true -] - -{ #category : #initialize } -MDLWidget class >> id: aStringID value: aBooleanValue [ - ^self new - id: aStringID; - value: aBooleanValue; - yourself -] - -{ #category : #id } -MDLWidget >> ensureId: html [ - self id ifNil: [ self id: html nextId ] -] - -{ #category : #accessing } -MDLWidget >> id [ - ^ id -] - -{ #category : #accessing } -MDLWidget >> id: anObject [ - id := anObject -] - -{ #category : #actions } -MDLWidget >> restoreFromSnapshot: anObject [ - | oldId | - oldId := self id. - super restoreFromSnapshot: anObject. - self id: oldId -] - -{ #category : #accessing } -MDLWidget >> value [ - ^ value -] - -{ #category : #accessing } -MDLWidget >> value: anObject [ - value := anObject -] +Class { + #name : #MDLWidget, + #superclass : #WAComponent, + #instVars : [ + 'id', + 'value' + ], + #category : 'Material-Design-Lite-Widgets' +} + +{ #category : #initialize } +MDLWidget class >> id: aStringID [ + ^self id: aStringID value: true +] + +{ #category : #initialize } +MDLWidget class >> id: aStringID value: aBooleanValue [ + ^self new + id: aStringID; + value: aBooleanValue; + yourself +] + +{ #category : #id } +MDLWidget >> ensureId: html [ + self id ifNil: [ self id: html nextId ] +] + +{ #category : #accessing } +MDLWidget >> id [ + ^ id +] + +{ #category : #accessing } +MDLWidget >> id: anObject [ + id := anObject +] + +{ #category : #actions } +MDLWidget >> restoreFromSnapshot: anObject [ + | oldId | + oldId := self id. + super restoreFromSnapshot: anObject. + self id: oldId +] + +{ #category : #accessing } +MDLWidget >> value [ + ^ value +] + +{ #category : #accessing } +MDLWidget >> value: anObject [ + value := anObject +] diff --git a/src/Material-Design-Lite-Widgets/ManifestMaterialDesignLiteWidgets.class.st b/src/Material-Design-Lite-Widgets/ManifestMaterialDesignLiteWidgets.class.st index 3d423394..b0ddb9a5 100644 --- a/src/Material-Design-Lite-Widgets/ManifestMaterialDesignLiteWidgets.class.st +++ b/src/Material-Design-Lite-Widgets/ManifestMaterialDesignLiteWidgets.class.st @@ -1,35 +1,35 @@ -" -I store metadata for this package. These meta data are used by other tools such as the SmalllintManifestChecker and the critics Browser -" -Class { - #name : #ManifestMaterialDesignLiteWidgets, - #superclass : #PackageManifest, - #category : 'Material-Design-Lite-Widgets-Manifest' -} - -{ #category : #'meta-data' } -ManifestMaterialDesignLiteWidgets class >> description [ ^ 'Material Design Lite for Seaside (MDL) is a library of components for web developers based on Google''s Material Design Philosophy: "A visual language for our users that synthesizes the classic principles of good design with the innovation and possibility of technology and science." Understanding the goals and principles of Material Design is critical to the proper use of the Material Design Lite components. If you have not yet read the Material Design Introduction you should do so before attempting to use the components. (See https://material.io/guidelines/material-design/) - -Github: https://github.com/DuneSt/MaterialDesignLite - -Demo: https://mdl.ferlicot.fr/ - -The second part of Material Design Lite for Seaside is the Widgets. Widgets are Seaside components with behaviour at the difference of MDL components. They respect Material Design rules and provide to the developers predefined behaviour. - -An exemple of widget is the nested list already containing features such as dynamic loading of elements, research, sorting...' -] - -{ #category : #'code-critics' } -ManifestMaterialDesignLiteWidgets class >> ruleGRAnsiConditionalsRuleV1FalsePositive [ - ^ #(#(#(#RGMethodDefinition #(#MDLTextFieldWidget #renderContentOn: #false)) #'2016-07-06T16:57:57.793+02:00') ) -] - -{ #category : #'code-critics' } -ManifestMaterialDesignLiteWidgets class >> ruleRBSendsDifferentSuperRuleV1FalsePositive [ - ^ #(#(#(#RGMethodDefinition #(#MDLLoginDialogWidget #renderLoginDialogOn: #false)) #'2016-07-11T14:50:20.68+02:00') ) -] - -{ #category : #'code-critics' } -ManifestMaterialDesignLiteWidgets class >> ruleRBTempsReadBeforeWrittenRuleV1FalsePositive [ - ^ #(#(#(#RGMethodDefinition #(#MDLTextFieldWidget #renderContentOn: #false)) #'2016-07-11T15:47:20.1+02:00') ) -] +" +I store metadata for this package. These meta data are used by other tools such as the SmalllintManifestChecker and the critics Browser +" +Class { + #name : #ManifestMaterialDesignLiteWidgets, + #superclass : #PackageManifest, + #category : 'Material-Design-Lite-Widgets-Manifest' +} + +{ #category : #'meta-data' } +ManifestMaterialDesignLiteWidgets class >> description [ ^ 'Material Design Lite for Seaside (MDL) is a library of components for web developers based on Google''s Material Design Philosophy: "A visual language for our users that synthesizes the classic principles of good design with the innovation and possibility of technology and science." Understanding the goals and principles of Material Design is critical to the proper use of the Material Design Lite components. If you have not yet read the Material Design Introduction you should do so before attempting to use the components. (See https://material.io/guidelines/material-design/) + +Github: https://github.com/DuneSt/MaterialDesignLite + +Demo: https://mdl.ferlicot.fr/ + +The second part of Material Design Lite for Seaside is the Widgets. Widgets are Seaside components with behaviour at the difference of MDL components. They respect Material Design rules and provide to the developers predefined behaviour. + +An exemple of widget is the nested list already containing features such as dynamic loading of elements, research, sorting...' +] + +{ #category : #'code-critics' } +ManifestMaterialDesignLiteWidgets class >> ruleGRAnsiConditionalsRuleV1FalsePositive [ + ^ #(#(#(#RGMethodDefinition #(#MDLTextFieldWidget #renderContentOn: #false)) #'2016-07-06T16:57:57.793+02:00') ) +] + +{ #category : #'code-critics' } +ManifestMaterialDesignLiteWidgets class >> ruleRBSendsDifferentSuperRuleV1FalsePositive [ + ^ #(#(#(#RGMethodDefinition #(#MDLLoginDialogWidget #renderLoginDialogOn: #false)) #'2016-07-11T14:50:20.68+02:00') ) +] + +{ #category : #'code-critics' } +ManifestMaterialDesignLiteWidgets class >> ruleRBTempsReadBeforeWrittenRuleV1FalsePositive [ + ^ #(#(#(#RGMethodDefinition #(#MDLTextFieldWidget #renderContentOn: #false)) #'2016-07-11T15:47:20.1+02:00') ) +] diff --git a/src/Material-Design-Lite-Widgets/Object.extension.st b/src/Material-Design-Lite-Widgets/Object.extension.st index b8d12fd2..c2cbdf14 100644 --- a/src/Material-Design-Lite-Widgets/Object.extension.st +++ b/src/Material-Design-Lite-Widgets/Object.extension.st @@ -1,11 +1,11 @@ -Extension { #name : #Object } - -{ #category : #'*Material-Design-Lite-Widgets' } -Object >> asMDLSortableTableHeader [ - ^ MDLSortableTableHeader for: self -] - -{ #category : #'*Material-Design-Lite-Widgets' } -Object >> asNumericMDLSortableTable [ - ^ MDLSortableTableHeaderNumeric for: self -] +Extension { #name : #Object } + +{ #category : #'*Material-Design-Lite-Widgets' } +Object >> asMDLSortableTableHeader [ + ^ MDLSortableTableHeader for: self +] + +{ #category : #'*Material-Design-Lite-Widgets' } +Object >> asNumericMDLSortableTable [ + ^ MDLSortableTableHeaderNumeric for: self +] diff --git a/src/Material-Design-Lite-Widgets/SequenceableCollection.extension.st b/src/Material-Design-Lite-Widgets/SequenceableCollection.extension.st index 8c39885a..3f5c8a47 100644 --- a/src/Material-Design-Lite-Widgets/SequenceableCollection.extension.st +++ b/src/Material-Design-Lite-Widgets/SequenceableCollection.extension.st @@ -1,13 +1,13 @@ -Extension { #name : #SequenceableCollection } - -{ #category : #'*Material-Design-Lite-Widgets' } -SequenceableCollection >> groupsOf: n [ - | grouped index | - grouped := self species new. - index := 1. - [ index > self size ] - whileFalse: [ grouped - add: (self copyFrom: index to: (index + n - 1 min: self size)) asArray. - index := index + n ]. - ^ grouped -] +Extension { #name : #SequenceableCollection } + +{ #category : #'*Material-Design-Lite-Widgets' } +SequenceableCollection >> groupsOf: n [ + | grouped index | + grouped := self species new. + index := 1. + [ index > self size ] + whileFalse: [ grouped + add: (self copyFrom: index to: (index + n - 1 min: self size)) asArray. + index := index + n ]. + ^ grouped +] diff --git a/src/Material-Design-Lite-Widgets/Symbol.extension.st b/src/Material-Design-Lite-Widgets/Symbol.extension.st index 0d18fe5f..10463929 100644 --- a/src/Material-Design-Lite-Widgets/Symbol.extension.st +++ b/src/Material-Design-Lite-Widgets/Symbol.extension.st @@ -1,11 +1,11 @@ -Extension { #name : #Symbol } - -{ #category : #'*Material-Design-Lite-Widgets' } -Symbol >> argumentCount [ - ^ 1 -] - -{ #category : #'*Material-Design-Lite-Widgets' } -Symbol >> mdlCull: anObject cull: anotherObject [ - ^ self cull: anObject -] +Extension { #name : #Symbol } + +{ #category : #'*Material-Design-Lite-Widgets' } +Symbol >> argumentCount [ + ^ 1 +] + +{ #category : #'*Material-Design-Lite-Widgets' } +Symbol >> mdlCull: anObject cull: anotherObject [ + ^ self cull: anObject +] diff --git a/src/Material-Design-Lite-Widgets/package.st b/src/Material-Design-Lite-Widgets/package.st index 9e430518..a4313d2d 100644 --- a/src/Material-Design-Lite-Widgets/package.st +++ b/src/Material-Design-Lite-Widgets/package.st @@ -1 +1 @@ -Package { #name : #'Material-Design-Lite-Widgets' } +Package { #name : #'Material-Design-Lite-Widgets' } From c3b716f932182db26c3bd41f03343f6953fe3da3 Mon Sep 17 00:00:00 2001 From: "yann.lesage" Date: Mon, 8 Nov 2021 12:12:09 +0100 Subject: [PATCH 2/2] remove whitespace and crlf changes --- .../BlockClosure.extension.st | 12 +- .../MDLAbstractFilter.class.st | 62 +- .../MDLAbstractFooterLinksList.class.st | 96 +- .../MDLAbstractHeaderSection.class.st | 28 +- .../MDLAbstractLayoutSection.class.st | 46 +- .../MDLAjaxButtonColumnDescription.class.st | 62 +- .../MDLAjaxExpansionStrategy.class.st | 76 +- .../MDLBeginsWithFilter.class.st | 26 +- .../MDLButtonColumnDescription.class.st | 174 +-- .../MDLCalendar.class.st | 262 ++-- .../MDLCardActionsWidget.class.st | 88 +- .../MDLCardMediaWidget.class.st | 56 +- .../MDLCardTextContainerWidget.class.st | 78 +- .../MDLCardTitle.class.st | 126 +- .../MDLCardWidget.class.st | 292 ++-- .../MDLContentCenterer.class.st | 140 +- .../MDLDatePicker.class.st | 52 +- .../MDLDialogWidget.class.st | 352 ++--- .../MDLExpansionPanel.class.st | 324 ++-- .../MDLExpansionStrategy.class.st | 46 +- .../MDLFlatDatePicker.class.st | 672 ++++----- .../MDLFooter.class.st | 164 +-- .../MDLFooterAbstractSection.class.st | 30 +- .../MDLFooterComponentsSection.class.st | 36 +- .../MDLFooterDropdownSection.class.st | 48 +- .../MDLFooterLinksSection.class.st | 48 +- .../MDLFooterNilSection.class.st | 40 +- .../MDLHideExpansionStrategy.class.st | 44 +- .../MDLHighLevelWidget.class.st | 228 +-- .../MDLIconComponent.class.st | 58 +- .../MDLIconDrawerSection.class.st | 52 +- .../MDLInsensitiveBeginsWithFilter.class.st | 26 +- .../MDLInsensitiveSubstringFilter.class.st | 26 +- .../MDLLayoutWidget.class.st | 220 +-- .../MDLLazyExpansionStrategy.class.st | 84 +- .../MDLLinkingLayoutSection.class.st | 78 +- .../MDLListIconComponent.class.st | 114 +- .../MDLLoginCardWidget.class.st | 42 +- .../MDLLoginDialogWidget.class.st | 152 +- .../MDLLoginWidget.class.st | 294 ++-- .../MDLMegaFooterLinksList.class.st | 22 +- .../MDLMenuButtonWidget.class.st | 552 +++---- .../MDLMiniFooterLinksList.class.st | 22 +- ...DLNavigationLinkWithIconComponent.class.st | 108 +- .../MDLNestedList.class.st | 1302 ++++++++--------- ...tedListItemRenderAbstractStrategy.class.st | 442 +++--- ...LNestedListItemRenderAjaxStrategy.class.st | 44 +- ...estedListItemRenderAnchorStrategy.class.st | 112 +- .../MDLNestedListTreeNode.class.st | 134 +- .../MDLNewPasswordWidget.class.st | 300 ++-- .../MDLNilLayoutSection.class.st | 20 +- .../MDLNumericColumnDescription.class.st | 50 +- .../MDLPoll.class.st | 122 +- .../MDLPollWidget.class.st | 196 +-- .../MDLProgressBarWidget.class.st | 256 ++-- .../MDLPseudoRegexFilter.class.st | 62 +- .../MDLSelectWidget.class.st | 866 +++++------ .../MDLSimpleDrawerSection.class.st | 24 +- .../MDLSimpleRowHeaderSection.class.st | 30 +- .../MDLSmallFooter.class.st | 88 +- .../MDLSortableTable.class.st | 652 ++++----- .../MDLSortableTableHeader.class.st | 180 +-- ...TableHeaderElementSortedAscending.class.st | 44 +- ...ableHeaderElementSortedDescending.class.st | 44 +- ...ortableTableHeaderElementUnsorted.class.st | 42 +- .../MDLSortableTableHeaderNumeric.class.st | 34 +- .../MDLSortableTableHeaderState.class.st | 86 +- .../MDLStringColumnDescription.class.st | 54 +- .../MDLSubstringFilter.class.st | 26 +- .../MDLSwitchWidget.class.st | 34 +- .../MDLTabWidget.class.st | 124 +- .../MDLTableColumnDescription.class.st | 152 +- .../MDLTableWidget.class.st | 248 ++-- .../MDLTextAreaWidget.class.st | 50 +- .../MDLTextFieldWidget.class.st | 378 ++--- .../MDLWidget.class.st | 110 +- ...ManifestMaterialDesignLiteWidgets.class.st | 70 +- .../Object.extension.st | 22 +- .../SequenceableCollection.extension.st | 26 +- .../Symbol.extension.st | 22 +- src/Material-Design-Lite-Widgets/package.st | 2 +- 81 files changed, 6003 insertions(+), 6003 deletions(-) diff --git a/src/Material-Design-Lite-Widgets/BlockClosure.extension.st b/src/Material-Design-Lite-Widgets/BlockClosure.extension.st index 8ef08634..7a37732c 100644 --- a/src/Material-Design-Lite-Widgets/BlockClosure.extension.st +++ b/src/Material-Design-Lite-Widgets/BlockClosure.extension.st @@ -1,6 +1,6 @@ -Extension { #name : #BlockClosure } - -{ #category : #'*Material-Design-Lite-Widgets' } -BlockClosure >> mdlCull: firstArg cull: secondArg [ - ^ self cull: firstArg cull: secondArg -] +Extension { #name : #BlockClosure } + +{ #category : #'*Material-Design-Lite-Widgets' } +BlockClosure >> mdlCull: firstArg cull: secondArg [ + ^ self cull: firstArg cull: secondArg +] diff --git a/src/Material-Design-Lite-Widgets/MDLAbstractFilter.class.st b/src/Material-Design-Lite-Widgets/MDLAbstractFilter.class.st index e6168d2a..8cc0bb48 100644 --- a/src/Material-Design-Lite-Widgets/MDLAbstractFilter.class.st +++ b/src/Material-Design-Lite-Widgets/MDLAbstractFilter.class.st @@ -1,31 +1,31 @@ -" -I am an abstract class managing the filtering of a nested list. I act in a design pattern strategy. - -My subclasses should be able to filter a MDLNestedList. - -Public API and Key Messages - -- class>>#isMatching: aString with: aPattern Return a boolean. True if the pattern matches the string, else false. -" -Class { - #name : #MDLAbstractFilter, - #superclass : #Object, - #category : #'Material-Design-Lite-Widgets-List' -} - -{ #category : #accessing } -MDLAbstractFilter class >> formatedElement: aString matches: aPattern [ - ^ self subclassResponsibility -] - -{ #category : #testing } -MDLAbstractFilter class >> isAbstract [ - ^ self = MDLAbstractFilter -] - -{ #category : #accessing } -MDLAbstractFilter class >> selectMatchingFrom: aCollection format: aFormatBlock with: aPattern [ - "I take as parameter a collection of elements to match, a block to get the readable format of the element and a pattern and I should return a collection of elements matching the pattern in their readable format." - - ^ aCollection select: [ :each | self formatedElement: (aFormatBlock value: each) matches: aPattern ] -] +" +I am an abstract class managing the filtering of a nested list. I act in a design pattern strategy. + +My subclasses should be able to filter a MDLNestedList. + +Public API and Key Messages + +- class>>#isMatching: aString with: aPattern Return a boolean. True if the pattern matches the string, else false. +" +Class { + #name : #MDLAbstractFilter, + #superclass : #Object, + #category : #'Material-Design-Lite-Widgets-List' +} + +{ #category : #accessing } +MDLAbstractFilter class >> formatedElement: aString matches: aPattern [ + ^ self subclassResponsibility +] + +{ #category : #testing } +MDLAbstractFilter class >> isAbstract [ + ^ self = MDLAbstractFilter +] + +{ #category : #accessing } +MDLAbstractFilter class >> selectMatchingFrom: aCollection format: aFormatBlock with: aPattern [ + "I take as parameter a collection of elements to match, a block to get the readable format of the element and a pattern and I should return a collection of elements matching the pattern in their readable format." + + ^ aCollection select: [ :each | self formatedElement: (aFormatBlock value: each) matches: aPattern ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLAbstractFooterLinksList.class.st b/src/Material-Design-Lite-Widgets/MDLAbstractFooterLinksList.class.st index 939574e2..1f1516a5 100644 --- a/src/Material-Design-Lite-Widgets/MDLAbstractFooterLinksList.class.st +++ b/src/Material-Design-Lite-Widgets/MDLAbstractFooterLinksList.class.st @@ -1,48 +1,48 @@ -Class { - #name : #MDLAbstractFooterLinksList, - #superclass : #Object, - #instVars : [ - 'links', - 'title' - ], - #category : 'Material-Design-Lite-Widgets-Footer' -} - -{ #category : #adding } -MDLAbstractFooterLinksList >> addLinks: l [ - "Links must be formatted as followed" - title := l key. - links addAll: l value -] - -{ #category : #initialization } -MDLAbstractFooterLinksList >> initialize [ - super initialize. - links := OrderedDictionary new -] - -{ #category : #'as yet unclassified' } -MDLAbstractFooterLinksList >> renderLinksListOn: html [ - self subclassResponsibility -] - -{ #category : #'as yet unclassified' } -MDLAbstractFooterLinksList >> renderLinksOn: html [ - links keysAndValuesDo: [ :label :callback | - html listItem: [ - html anchor - callback: callback; - with: label ] ] -] - -{ #category : #'as yet unclassified' } -MDLAbstractFooterLinksList >> renderLinksWithHeaderOn: html [ - html mdlFooterHeading: title. - self renderLinksListOn: html -] - -{ #category : #'as yet unclassified' } -MDLAbstractFooterLinksList >> renderLinksWithLogoOn: html [ - html mdlLogo: title. - self renderLinksListOn: html -] +Class { + #name : #MDLAbstractFooterLinksList, + #superclass : #Object, + #instVars : [ + 'links', + 'title' + ], + #category : 'Material-Design-Lite-Widgets-Footer' +} + +{ #category : #adding } +MDLAbstractFooterLinksList >> addLinks: l [ + "Links must be formatted as followed" + title := l key. + links addAll: l value +] + +{ #category : #initialization } +MDLAbstractFooterLinksList >> initialize [ + super initialize. + links := OrderedDictionary new +] + +{ #category : #'as yet unclassified' } +MDLAbstractFooterLinksList >> renderLinksListOn: html [ + self subclassResponsibility +] + +{ #category : #'as yet unclassified' } +MDLAbstractFooterLinksList >> renderLinksOn: html [ + links keysAndValuesDo: [ :label :callback | + html listItem: [ + html anchor + callback: callback; + with: label ] ] +] + +{ #category : #'as yet unclassified' } +MDLAbstractFooterLinksList >> renderLinksWithHeaderOn: html [ + html mdlFooterHeading: title. + self renderLinksListOn: html +] + +{ #category : #'as yet unclassified' } +MDLAbstractFooterLinksList >> renderLinksWithLogoOn: html [ + html mdlLogo: title. + self renderLinksListOn: html +] diff --git a/src/Material-Design-Lite-Widgets/MDLAbstractHeaderSection.class.st b/src/Material-Design-Lite-Widgets/MDLAbstractHeaderSection.class.st index 370e5019..c1c685c4 100644 --- a/src/Material-Design-Lite-Widgets/MDLAbstractHeaderSection.class.st +++ b/src/Material-Design-Lite-Widgets/MDLAbstractHeaderSection.class.st @@ -1,14 +1,14 @@ -Class { - #name : #MDLAbstractHeaderSection, - #superclass : #MDLLinkingLayoutSection, - #instVars : [ - 'brush' - ], - #category : 'Material-Design-Lite-Widgets-Header' -} - -{ #category : #initialization } -MDLAbstractHeaderSection >> initialize [ - super initialize. - brush := MDLLayoutHeader new -] +Class { + #name : #MDLAbstractHeaderSection, + #superclass : #MDLLinkingLayoutSection, + #instVars : [ + 'brush' + ], + #category : 'Material-Design-Lite-Widgets-Header' +} + +{ #category : #initialization } +MDLAbstractHeaderSection >> initialize [ + super initialize. + brush := MDLLayoutHeader new +] diff --git a/src/Material-Design-Lite-Widgets/MDLAbstractLayoutSection.class.st b/src/Material-Design-Lite-Widgets/MDLAbstractLayoutSection.class.st index ca60fe49..2ca80d24 100644 --- a/src/Material-Design-Lite-Widgets/MDLAbstractLayoutSection.class.st +++ b/src/Material-Design-Lite-Widgets/MDLAbstractLayoutSection.class.st @@ -1,23 +1,23 @@ -Class { - #name : #MDLAbstractLayoutSection, - #superclass : #MDLWidget, - #instVars : [ - 'layout' - ], - #category : 'Material-Design-Lite-Widgets-Header' -} - -{ #category : #accessing } -MDLAbstractLayoutSection >> layout [ - ^ layout -] - -{ #category : #accessing } -MDLAbstractLayoutSection >> layout: anObject [ - layout := anObject -] - -{ #category : #rendering } -MDLAbstractLayoutSection >> renderContentOn: html [ - self subclassResponsibility -] +Class { + #name : #MDLAbstractLayoutSection, + #superclass : #MDLWidget, + #instVars : [ + 'layout' + ], + #category : 'Material-Design-Lite-Widgets-Header' +} + +{ #category : #accessing } +MDLAbstractLayoutSection >> layout [ + ^ layout +] + +{ #category : #accessing } +MDLAbstractLayoutSection >> layout: anObject [ + layout := anObject +] + +{ #category : #rendering } +MDLAbstractLayoutSection >> renderContentOn: html [ + self subclassResponsibility +] diff --git a/src/Material-Design-Lite-Widgets/MDLAjaxButtonColumnDescription.class.st b/src/Material-Design-Lite-Widgets/MDLAjaxButtonColumnDescription.class.st index 41e553db..6e2a97ef 100644 --- a/src/Material-Design-Lite-Widgets/MDLAjaxButtonColumnDescription.class.st +++ b/src/Material-Design-Lite-Widgets/MDLAjaxButtonColumnDescription.class.st @@ -1,31 +1,31 @@ -" -I am a button performing its action via AJAX which means that my user control what parts of the page need to be refreshed. - -My #onClickBlock has two arguments: the html canvas to generate javascript on and the row on which the action should be applied. -" -Class { - #name : #MDLAjaxButtonColumnDescription, - #superclass : #MDLButtonColumnDescription, - #category : #'Material-Design-Lite-Widgets-Table' -} - -{ #category : #initialization } -MDLAjaxButtonColumnDescription >> initialize [ - super initialize. - "Initialize with a behaviour that does nothing." - self onClickBlock: [ :html :rowObject | html jQuery noop ] -] - -{ #category : #rendering } -MDLAjaxButtonColumnDescription >> render: row on: html [ - | buttonId | - html mdlTableCell - with: [ - html mdlButton - class: 'mdl-table-widget__cell--button'; - id: (buttonId := self generateIdUsing: html); - onClick: (self onClickBlock value: html value: row); - labelIcon: self iconName ]. - - self renderTooltipFor: buttonId on: html -] +" +I am a button performing its action via AJAX which means that my user control what parts of the page need to be refreshed. + +My #onClickBlock has two arguments: the html canvas to generate javascript on and the row on which the action should be applied. +" +Class { + #name : #MDLAjaxButtonColumnDescription, + #superclass : #MDLButtonColumnDescription, + #category : #'Material-Design-Lite-Widgets-Table' +} + +{ #category : #initialization } +MDLAjaxButtonColumnDescription >> initialize [ + super initialize. + "Initialize with a behaviour that does nothing." + self onClickBlock: [ :html :rowObject | html jQuery noop ] +] + +{ #category : #rendering } +MDLAjaxButtonColumnDescription >> render: row on: html [ + | buttonId | + html mdlTableCell + with: [ + html mdlButton + class: 'mdl-table-widget__cell--button'; + id: (buttonId := self generateIdUsing: html); + onClick: (self onClickBlock value: html value: row); + labelIcon: self iconName ]. + + self renderTooltipFor: buttonId on: html +] diff --git a/src/Material-Design-Lite-Widgets/MDLAjaxExpansionStrategy.class.st b/src/Material-Design-Lite-Widgets/MDLAjaxExpansionStrategy.class.st index 74897387..b8a98e78 100644 --- a/src/Material-Design-Lite-Widgets/MDLAjaxExpansionStrategy.class.st +++ b/src/Material-Design-Lite-Widgets/MDLAjaxExpansionStrategy.class.st @@ -1,38 +1,38 @@ -" -I am display strategy that uses AJAX to reload the entire MDLExpansionPanel each time the toggle button is clicked. - -Because of my behaviour, one can define an action to execute on server side either when I expand (#onExpandBlock:) or when I fold (#onFoldBlock:). -These actions can eventually modify the state of the expansion panel as the full widget is reload via AJAX. -" -Class { - #name : #MDLAjaxExpansionStrategy, - #superclass : #MDLExpansionStrategy, - #instVars : [ - 'onFoldBlock', - 'onExpandBlock' - ], - #category : #'Material-Design-Lite-Widgets-Expansion' -} - -{ #category : #javascript } -MDLAjaxExpansionStrategy >> customize: anExpansionPanelHeader in: anExpansionPanel on: html [ - anExpansionPanelHeader - onClick: - ((html jQuery this parent find: '.mdl-expansion-panel__content') load - html: [ :ajaxHtmlCanvas | - anExpansionPanel - toggleExpansion; - renderExpansionPanelContentOn: ajaxHtmlCanvas ]; - onComplete: 'componentHandler.upgradeElements(this);' js) -] - -{ #category : #testing } -MDLAjaxExpansionStrategy >> isAjaxExpansionStrategy [ - ^ true -] - -{ #category : #rendering } -MDLAjaxExpansionStrategy >> renderExpansionPanel: anExpansionPanel contentOn: html [ - anExpansionPanel isExpanded - ifTrue: [ anExpansionPanel expandedBlock value: html ] -] +" +I am display strategy that uses AJAX to reload the entire MDLExpansionPanel each time the toggle button is clicked. + +Because of my behaviour, one can define an action to execute on server side either when I expand (#onExpandBlock:) or when I fold (#onFoldBlock:). +These actions can eventually modify the state of the expansion panel as the full widget is reload via AJAX. +" +Class { + #name : #MDLAjaxExpansionStrategy, + #superclass : #MDLExpansionStrategy, + #instVars : [ + 'onFoldBlock', + 'onExpandBlock' + ], + #category : #'Material-Design-Lite-Widgets-Expansion' +} + +{ #category : #javascript } +MDLAjaxExpansionStrategy >> customize: anExpansionPanelHeader in: anExpansionPanel on: html [ + anExpansionPanelHeader + onClick: + ((html jQuery this parent find: '.mdl-expansion-panel__content') load + html: [ :ajaxHtmlCanvas | + anExpansionPanel + toggleExpansion; + renderExpansionPanelContentOn: ajaxHtmlCanvas ]; + onComplete: 'componentHandler.upgradeElements(this);' js) +] + +{ #category : #testing } +MDLAjaxExpansionStrategy >> isAjaxExpansionStrategy [ + ^ true +] + +{ #category : #rendering } +MDLAjaxExpansionStrategy >> renderExpansionPanel: anExpansionPanel contentOn: html [ + anExpansionPanel isExpanded + ifTrue: [ anExpansionPanel expandedBlock value: html ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLBeginsWithFilter.class.st b/src/Material-Design-Lite-Widgets/MDLBeginsWithFilter.class.st index 69414fb4..e53ee53e 100644 --- a/src/Material-Design-Lite-Widgets/MDLBeginsWithFilter.class.st +++ b/src/Material-Design-Lite-Widgets/MDLBeginsWithFilter.class.st @@ -1,13 +1,13 @@ -" -I am a nested list filter keeping only elements whose name begins with the pattern passed by the user. -" -Class { - #name : #MDLBeginsWithFilter, - #superclass : #MDLAbstractFilter, - #category : 'Material-Design-Lite-Widgets-List' -} - -{ #category : #accessing } -MDLBeginsWithFilter class >> formatedElement: aString matches: aPattern [ - ^ aString beginsWith: aPattern -] +" +I am a nested list filter keeping only elements whose name begins with the pattern passed by the user. +" +Class { + #name : #MDLBeginsWithFilter, + #superclass : #MDLAbstractFilter, + #category : 'Material-Design-Lite-Widgets-List' +} + +{ #category : #accessing } +MDLBeginsWithFilter class >> formatedElement: aString matches: aPattern [ + ^ aString beginsWith: aPattern +] diff --git a/src/Material-Design-Lite-Widgets/MDLButtonColumnDescription.class.st b/src/Material-Design-Lite-Widgets/MDLButtonColumnDescription.class.st index 28b5e00a..6fb9f732 100644 --- a/src/Material-Design-Lite-Widgets/MDLButtonColumnDescription.class.st +++ b/src/Material-Design-Lite-Widgets/MDLButtonColumnDescription.class.st @@ -1,87 +1,87 @@ -" -I model a button column. - -I add a button to each row which should perform an action concerning the row. - -I perform my action in a callback which means that the page is refreshed when a button is clicked. - -My #onClickBlock has a single argument: the row on which the action should be applied. - -A #tooltip can bet set to display useful information to user about the purpose of my buttons. -" -Class { - #name : #MDLButtonColumnDescription, - #superclass : #MDLTableColumnDescription, - #instVars : [ - 'onClickBlock', - 'iconName', - 'tooltip' - ], - #category : #'Material-Design-Lite-Widgets-Table' -} - -{ #category : #accessing } -MDLButtonColumnDescription >> iconName [ - ^ iconName -] - -{ #category : #accessing } -MDLButtonColumnDescription >> iconName: anObject [ - iconName := anObject -] - -{ #category : #initialization } -MDLButtonColumnDescription >> initialize [ - super initialize. - "Initialize with a behaviour that does nothing." - self onClickBlock: [ ] -] - -{ #category : #accessing } -MDLButtonColumnDescription >> onClickBlock [ - ^ onClickBlock -] - -{ #category : #accessing } -MDLButtonColumnDescription >> onClickBlock: anObject [ - onClickBlock := anObject -] - -{ #category : #rendering } -MDLButtonColumnDescription >> render: row on: html [ - | buttonId | - html mdlTableCell - class: 'mdl-table-widget__cell--button'; - with: [ html mdlAnchorButton - id: (buttonId := self generateIdUsing: html); - callback: [ self onClickBlock value: row ]; - icon: self iconName ]. - - self renderTooltipFor: buttonId on: html -] - -{ #category : #rendering } -MDLButtonColumnDescription >> renderHeadingOn: html [ - (super renderHeadingOn: html) - class: 'mdl-table-widget__cell--button'; - nonNumerical; - with: self title. -] - -{ #category : #rendering } -MDLButtonColumnDescription >> renderTooltipFor: buttonId on: html [ - self tooltip ifNil: [ ^ self ]. - html mdlTooltip - for: buttonId; - with: [ html text: self tooltip ] -] - -{ #category : #accessing } -MDLButtonColumnDescription >> tooltip [ - ^ tooltip -] - -{ #category : #accessing } -MDLButtonColumnDescription >> tooltip: anObject [ - tooltip := anObject -] +" +I model a button column. + +I add a button to each row which should perform an action concerning the row. + +I perform my action in a callback which means that the page is refreshed when a button is clicked. + +My #onClickBlock has a single argument: the row on which the action should be applied. + +A #tooltip can bet set to display useful information to user about the purpose of my buttons. +" +Class { + #name : #MDLButtonColumnDescription, + #superclass : #MDLTableColumnDescription, + #instVars : [ + 'onClickBlock', + 'iconName', + 'tooltip' + ], + #category : #'Material-Design-Lite-Widgets-Table' +} + +{ #category : #accessing } +MDLButtonColumnDescription >> iconName [ + ^ iconName +] + +{ #category : #accessing } +MDLButtonColumnDescription >> iconName: anObject [ + iconName := anObject +] + +{ #category : #initialization } +MDLButtonColumnDescription >> initialize [ + super initialize. + "Initialize with a behaviour that does nothing." + self onClickBlock: [ ] +] + +{ #category : #accessing } +MDLButtonColumnDescription >> onClickBlock [ + ^ onClickBlock +] + +{ #category : #accessing } +MDLButtonColumnDescription >> onClickBlock: anObject [ + onClickBlock := anObject +] + +{ #category : #rendering } +MDLButtonColumnDescription >> render: row on: html [ + | buttonId | + html mdlTableCell + class: 'mdl-table-widget__cell--button'; + with: [ html mdlAnchorButton + id: (buttonId := self generateIdUsing: html); + callback: [ self onClickBlock value: row ]; + icon: self iconName ]. + + self renderTooltipFor: buttonId on: html +] + +{ #category : #rendering } +MDLButtonColumnDescription >> renderHeadingOn: html [ + (super renderHeadingOn: html) + class: 'mdl-table-widget__cell--button'; + nonNumerical; + with: self title. +] + +{ #category : #rendering } +MDLButtonColumnDescription >> renderTooltipFor: buttonId on: html [ + self tooltip ifNil: [ ^ self ]. + html mdlTooltip + for: buttonId; + with: [ html text: self tooltip ] +] + +{ #category : #accessing } +MDLButtonColumnDescription >> tooltip [ + ^ tooltip +] + +{ #category : #accessing } +MDLButtonColumnDescription >> tooltip: anObject [ + tooltip := anObject +] diff --git a/src/Material-Design-Lite-Widgets/MDLCalendar.class.st b/src/Material-Design-Lite-Widgets/MDLCalendar.class.st index e2619763..657d94e6 100644 --- a/src/Material-Design-Lite-Widgets/MDLCalendar.class.st +++ b/src/Material-Design-Lite-Widgets/MDLCalendar.class.st @@ -1,131 +1,131 @@ -" -firstDayOfWeekIndex is the index of the first day of the week in the representation, 7 being saturday and 1 sunday -" -Class { - #name : #MDLCalendar, - #superclass : #Object, - #instVars : [ - 'currentDate', - 'firstDayOfWeekIndex', - 'yearsInterval' - ], - #category : 'Material-Design-Lite-Widgets-Calendar' -} - -{ #category : #accessing } -MDLCalendar >> currentDate [ - ^ currentDate -] - -{ #category : #accessing } -MDLCalendar >> currentDate: anObject [ - yearsInterval := anObject year - 4 to: anObject year + 4. - currentDate := anObject -] - -{ #category : #'computing weeks' } -MDLCalendar >> daysForWeek: i [ - "Return an array of 7 days for the desired week" - | dayCount firstWeekday previousDayCount previousMonthDays lastDayofPreviousWeek | - i < 1 | (i > 6) ifTrue: [ Error signal: 'Wrong week index' ]. - dayCount := currentDate asMonth daysInMonth . - firstWeekday := Date firstWeekdayOfMonth: currentDate monthIndex year: currentDate year. - previousDayCount := currentDate asMonth previous daysInMonth. - - i = 1 ifTrue: [ - "If this month's first day is the first day in the representation, - the first line is the last week from last month" - firstWeekday = self firstDayOfWeekIndex - ifTrue: [ ^ (previousDayCount - 6 to: previousDayCount) asArray]. - - "Otherwise, its a mix of last month and this month" - previousMonthDays := (firstWeekday - self firstDayOfWeekIndex to: 1 by: -1) collect: [:each | previousDayCount - each + 1]. - ^ previousMonthDays, (1 to: 7 - previousMonthDays size) asArray - ]. - - "Recompute the last day from the previous line" - lastDayofPreviousWeek := (self daysForWeek: i - 1) last. - - "The first week of this month or the first week of next month - begin with the first day of the week " - ((i = 2 and: [ lastDayofPreviousWeek = previousDayCount ]) - or: [ lastDayofPreviousWeek = dayCount ]) - ifTrue: [ ^ (1 to: 7) asArray ]. - - ^ (lastDayofPreviousWeek + 1 to: lastDayofPreviousWeek + 7) collect: - [ :each | - each <= dayCount - ifTrue: [ each ] - ifFalse: [ each - dayCount ] - ] -] - -{ #category : #accessing } -MDLCalendar >> firstDayOfWeekIndex [ - ^ firstDayOfWeekIndex -] - -{ #category : #accessing } -MDLCalendar >> firstDayOfWeekIndex: anInteger [ - firstDayOfWeekIndex := anInteger -] - -{ #category : #accessing } -MDLCalendar >> goToMonth: anIndex [ - | oldIndex | - oldIndex := currentDate monthIndex. - self currentDate: (currentDate addMonths: anIndex - oldIndex) -] - -{ #category : #accessing } -MDLCalendar >> goToYear: aNumber [ - self currentDate: (currentDate addMonths: (aNumber - currentDate year) * 12) -] - -{ #category : #initialization } -MDLCalendar >> initialize [ - super initialize. - self currentDate: Date today. - self firstDayOfWeekIndex: 1 -] - -{ #category : #printing } -MDLCalendar >> printDateForHeader [ - ^ String - streamContents: [ :s | - s - nextPutAll: self currentDate asDateAndTime dayOfWeekAbbreviation; - nextPutAll: ', '; - nextPutAll: self currentDate monthAbbreviation; - space; - print: self currentDate dayOfMonth ] -] - -{ #category : #accessing } -MDLCalendar >> selectNextMonth [ - currentDate := currentDate onNextMonth -] - -{ #category : #accessing } -MDLCalendar >> selectNextYears [ - yearsInterval := yearsInterval + 9 -] - -{ #category : #accessing } -MDLCalendar >> selectPreviousMonth [ - currentDate := currentDate onPreviousMonth -] - -{ #category : #accessing } -MDLCalendar >> selectPreviousYears [ - yearsInterval := yearsInterval - 9 -] - -{ #category : #accessing } -MDLCalendar >> yearsInterval [ - "This will be removed. In the calendar we let the user select the year by displaying year 9 by 9. 4 before the current year, 4 after the current year by default. - - I think this should not be the responsibility of the MDLCalendar but of the MDLCalendarWidget? See https://github.com/DuneSt/MaterialDesignLite/issues/178" - - ^ yearsInterval -] +" +firstDayOfWeekIndex is the index of the first day of the week in the representation, 7 being saturday and 1 sunday +" +Class { + #name : #MDLCalendar, + #superclass : #Object, + #instVars : [ + 'currentDate', + 'firstDayOfWeekIndex', + 'yearsInterval' + ], + #category : 'Material-Design-Lite-Widgets-Calendar' +} + +{ #category : #accessing } +MDLCalendar >> currentDate [ + ^ currentDate +] + +{ #category : #accessing } +MDLCalendar >> currentDate: anObject [ + yearsInterval := anObject year - 4 to: anObject year + 4. + currentDate := anObject +] + +{ #category : #'computing weeks' } +MDLCalendar >> daysForWeek: i [ + "Return an array of 7 days for the desired week" + | dayCount firstWeekday previousDayCount previousMonthDays lastDayofPreviousWeek | + i < 1 | (i > 6) ifTrue: [ Error signal: 'Wrong week index' ]. + dayCount := currentDate asMonth daysInMonth . + firstWeekday := Date firstWeekdayOfMonth: currentDate monthIndex year: currentDate year. + previousDayCount := currentDate asMonth previous daysInMonth. + + i = 1 ifTrue: [ + "If this month's first day is the first day in the representation, + the first line is the last week from last month" + firstWeekday = self firstDayOfWeekIndex + ifTrue: [ ^ (previousDayCount - 6 to: previousDayCount) asArray]. + + "Otherwise, its a mix of last month and this month" + previousMonthDays := (firstWeekday - self firstDayOfWeekIndex to: 1 by: -1) collect: [:each | previousDayCount - each + 1]. + ^ previousMonthDays, (1 to: 7 - previousMonthDays size) asArray + ]. + + "Recompute the last day from the previous line" + lastDayofPreviousWeek := (self daysForWeek: i - 1) last. + + "The first week of this month or the first week of next month + begin with the first day of the week " + ((i = 2 and: [ lastDayofPreviousWeek = previousDayCount ]) + or: [ lastDayofPreviousWeek = dayCount ]) + ifTrue: [ ^ (1 to: 7) asArray ]. + + ^ (lastDayofPreviousWeek + 1 to: lastDayofPreviousWeek + 7) collect: + [ :each | + each <= dayCount + ifTrue: [ each ] + ifFalse: [ each - dayCount ] + ] +] + +{ #category : #accessing } +MDLCalendar >> firstDayOfWeekIndex [ + ^ firstDayOfWeekIndex +] + +{ #category : #accessing } +MDLCalendar >> firstDayOfWeekIndex: anInteger [ + firstDayOfWeekIndex := anInteger +] + +{ #category : #accessing } +MDLCalendar >> goToMonth: anIndex [ + | oldIndex | + oldIndex := currentDate monthIndex. + self currentDate: (currentDate addMonths: anIndex - oldIndex) +] + +{ #category : #accessing } +MDLCalendar >> goToYear: aNumber [ + self currentDate: (currentDate addMonths: (aNumber - currentDate year) * 12) +] + +{ #category : #initialization } +MDLCalendar >> initialize [ + super initialize. + self currentDate: Date today. + self firstDayOfWeekIndex: 1 +] + +{ #category : #printing } +MDLCalendar >> printDateForHeader [ + ^ String + streamContents: [ :s | + s + nextPutAll: self currentDate asDateAndTime dayOfWeekAbbreviation; + nextPutAll: ', '; + nextPutAll: self currentDate monthAbbreviation; + space; + print: self currentDate dayOfMonth ] +] + +{ #category : #accessing } +MDLCalendar >> selectNextMonth [ + currentDate := currentDate onNextMonth +] + +{ #category : #accessing } +MDLCalendar >> selectNextYears [ + yearsInterval := yearsInterval + 9 +] + +{ #category : #accessing } +MDLCalendar >> selectPreviousMonth [ + currentDate := currentDate onPreviousMonth +] + +{ #category : #accessing } +MDLCalendar >> selectPreviousYears [ + yearsInterval := yearsInterval - 9 +] + +{ #category : #accessing } +MDLCalendar >> yearsInterval [ + "This will be removed. In the calendar we let the user select the year by displaying year 9 by 9. 4 before the current year, 4 after the current year by default. + + I think this should not be the responsibility of the MDLCalendar but of the MDLCalendarWidget? See https://github.com/DuneSt/MaterialDesignLite/issues/178" + + ^ yearsInterval +] diff --git a/src/Material-Design-Lite-Widgets/MDLCardActionsWidget.class.st b/src/Material-Design-Lite-Widgets/MDLCardActionsWidget.class.st index c3a43d85..be74adbc 100644 --- a/src/Material-Design-Lite-Widgets/MDLCardActionsWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLCardActionsWidget.class.st @@ -1,44 +1,44 @@ -" -Widget for actions -" -Class { - #name : #MDLCardActionsWidget, - #superclass : #MDLHighLevelWidget, - #instVars : [ - 'componentOrBlocks', - 'bordered' - ], - #category : 'Material-Design-Lite-Widgets-Cards' -} - -{ #category : #adding } -MDLCardActionsWidget >> addComponentOrBlock: aComponentOrBlock [ - componentOrBlocks add: aComponentOrBlock -] - -{ #category : #options } -MDLCardActionsWidget >> beBordered [ - bordered := true -] - -{ #category : #initialization } -MDLCardActionsWidget >> initialize [ - super initialize. - bordered := false. - componentOrBlocks := OrderedCollection new -] - -{ #category : #rendering } -MDLCardActionsWidget >> renderContentOn: html [ - | cardActions | - cardActions := html mdlCardActions. - self addPropertiesToBrush: cardActions. - bordered - ifTrue: [ cardActions border ]. - cardActions - with: [ componentOrBlocks - do: [ :aComponentOrBlock | - aComponentOrBlock isBlock - ifTrue: [ aComponentOrBlock cull: html ] - ifFalse: [ html render: aComponentOrBlock ] ] ] -] +" +Widget for actions +" +Class { + #name : #MDLCardActionsWidget, + #superclass : #MDLHighLevelWidget, + #instVars : [ + 'componentOrBlocks', + 'bordered' + ], + #category : 'Material-Design-Lite-Widgets-Cards' +} + +{ #category : #adding } +MDLCardActionsWidget >> addComponentOrBlock: aComponentOrBlock [ + componentOrBlocks add: aComponentOrBlock +] + +{ #category : #options } +MDLCardActionsWidget >> beBordered [ + bordered := true +] + +{ #category : #initialization } +MDLCardActionsWidget >> initialize [ + super initialize. + bordered := false. + componentOrBlocks := OrderedCollection new +] + +{ #category : #rendering } +MDLCardActionsWidget >> renderContentOn: html [ + | cardActions | + cardActions := html mdlCardActions. + self addPropertiesToBrush: cardActions. + bordered + ifTrue: [ cardActions border ]. + cardActions + with: [ componentOrBlocks + do: [ :aComponentOrBlock | + aComponentOrBlock isBlock + ifTrue: [ aComponentOrBlock cull: html ] + ifFalse: [ html render: aComponentOrBlock ] ] ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLCardMediaWidget.class.st b/src/Material-Design-Lite-Widgets/MDLCardMediaWidget.class.st index 20d16c10..dd93c373 100644 --- a/src/Material-Design-Lite-Widgets/MDLCardMediaWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLCardMediaWidget.class.st @@ -1,28 +1,28 @@ -" -I represent a card media widget -" -Class { - #name : #MDLCardMediaWidget, - #superclass : #MDLHighLevelWidget, - #instVars : [ - 'content' - ], - #category : 'Material-Design-Lite-Widgets-Cards' -} - -{ #category : #'instance creation' } -MDLCardMediaWidget class >> newWith: aBlock [ - ^ self new - content: aBlock; - yourself -] - -{ #category : #accessing } -MDLCardMediaWidget >> content: aBlock [ - content := aBlock -] - -{ #category : #rendering } -MDLCardMediaWidget >> renderContentOn: html [ - html mdlCardMedia: [ content value: html ] -] +" +I represent a card media widget +" +Class { + #name : #MDLCardMediaWidget, + #superclass : #MDLHighLevelWidget, + #instVars : [ + 'content' + ], + #category : 'Material-Design-Lite-Widgets-Cards' +} + +{ #category : #'instance creation' } +MDLCardMediaWidget class >> newWith: aBlock [ + ^ self new + content: aBlock; + yourself +] + +{ #category : #accessing } +MDLCardMediaWidget >> content: aBlock [ + content := aBlock +] + +{ #category : #rendering } +MDLCardMediaWidget >> renderContentOn: html [ + html mdlCardMedia: [ content value: html ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLCardTextContainerWidget.class.st b/src/Material-Design-Lite-Widgets/MDLCardTextContainerWidget.class.st index 919670c8..89b8f986 100644 --- a/src/Material-Design-Lite-Widgets/MDLCardTextContainerWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLCardTextContainerWidget.class.st @@ -1,39 +1,39 @@ -" -Widget for text container -" -Class { - #name : #MDLCardTextContainerWidget, - #superclass : #MDLHighLevelWidget, - #instVars : [ - 'content' - ], - #category : 'Material-Design-Lite-Widgets-Cards' -} - -{ #category : #'instance creation' } -MDLCardTextContainerWidget class >> newWithContent: anObject [ - ^ self new - content: anObject; - yourself -] - -{ #category : #'instance creation' } -MDLCardTextContainerWidget class >> newWithContent: anObject class: cssClasses [ - ^ self new - content: anObject; - class: cssClasses; - yourself -] - -{ #category : #accessing } -MDLCardTextContainerWidget >> content: text [ - content := text -] - -{ #category : #rendering } -MDLCardTextContainerWidget >> renderContentOn: html [ - | brush | - brush := html mdlCardTextContainer. - self addPropertiesToBrush: brush. - brush with: content -] +" +Widget for text container +" +Class { + #name : #MDLCardTextContainerWidget, + #superclass : #MDLHighLevelWidget, + #instVars : [ + 'content' + ], + #category : 'Material-Design-Lite-Widgets-Cards' +} + +{ #category : #'instance creation' } +MDLCardTextContainerWidget class >> newWithContent: anObject [ + ^ self new + content: anObject; + yourself +] + +{ #category : #'instance creation' } +MDLCardTextContainerWidget class >> newWithContent: anObject class: cssClasses [ + ^ self new + content: anObject; + class: cssClasses; + yourself +] + +{ #category : #accessing } +MDLCardTextContainerWidget >> content: text [ + content := text +] + +{ #category : #rendering } +MDLCardTextContainerWidget >> renderContentOn: html [ + | brush | + brush := html mdlCardTextContainer. + self addPropertiesToBrush: brush. + brush with: content +] diff --git a/src/Material-Design-Lite-Widgets/MDLCardTitle.class.st b/src/Material-Design-Lite-Widgets/MDLCardTitle.class.st index 21f7ce1d..0600c612 100644 --- a/src/Material-Design-Lite-Widgets/MDLCardTitle.class.st +++ b/src/Material-Design-Lite-Widgets/MDLCardTitle.class.st @@ -1,63 +1,63 @@ -" -I represent a widget for card title -" -Class { - #name : #MDLCardTitle, - #superclass : #MDLHighLevelWidget, - #instVars : [ - 'level', - 'title' - ], - #category : 'Material-Design-Lite-Widgets-Cards' -} - -{ #category : #'instance creation' } -MDLCardTitle class >> newWithTitle: aString level: aNumber [ - ^ self new - title: aString; - level: aNumber; - yourself -] - -{ #category : #'instance creation' } -MDLCardTitle class >> newWithTitle: aString level: aNumber class: cssClasses [ - ^ self new - title: aString; - level: aNumber; - class: cssClasses; - yourself -] - -{ #category : #initialization } -MDLCardTitle >> initialize [ - super initialize. - level := 2. -] - -{ #category : #accessing } -MDLCardTitle >> level [ - ^ level -] - -{ #category : #accessing } -MDLCardTitle >> level: anObject [ - level := anObject -] - -{ #category : #rendering } -MDLCardTitle >> renderContentOn: html [ - | brush | - brush := html mdlCardTitleContainer. - self addPropertiesToBrush: brush. - brush with: [ html mdlCardTitleText: self title level: self level ] -] - -{ #category : #accessing } -MDLCardTitle >> title [ - ^ title -] - -{ #category : #accessing } -MDLCardTitle >> title: anObject [ - title := anObject -] +" +I represent a widget for card title +" +Class { + #name : #MDLCardTitle, + #superclass : #MDLHighLevelWidget, + #instVars : [ + 'level', + 'title' + ], + #category : 'Material-Design-Lite-Widgets-Cards' +} + +{ #category : #'instance creation' } +MDLCardTitle class >> newWithTitle: aString level: aNumber [ + ^ self new + title: aString; + level: aNumber; + yourself +] + +{ #category : #'instance creation' } +MDLCardTitle class >> newWithTitle: aString level: aNumber class: cssClasses [ + ^ self new + title: aString; + level: aNumber; + class: cssClasses; + yourself +] + +{ #category : #initialization } +MDLCardTitle >> initialize [ + super initialize. + level := 2. +] + +{ #category : #accessing } +MDLCardTitle >> level [ + ^ level +] + +{ #category : #accessing } +MDLCardTitle >> level: anObject [ + level := anObject +] + +{ #category : #rendering } +MDLCardTitle >> renderContentOn: html [ + | brush | + brush := html mdlCardTitleContainer. + self addPropertiesToBrush: brush. + brush with: [ html mdlCardTitleText: self title level: self level ] +] + +{ #category : #accessing } +MDLCardTitle >> title [ + ^ title +] + +{ #category : #accessing } +MDLCardTitle >> title: anObject [ + title := anObject +] diff --git a/src/Material-Design-Lite-Widgets/MDLCardWidget.class.st b/src/Material-Design-Lite-Widgets/MDLCardWidget.class.st index 8038e73f..2cac3075 100644 --- a/src/Material-Design-Lite-Widgets/MDLCardWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLCardWidget.class.st @@ -1,146 +1,146 @@ -" -High level widget to render a card -" -Class { - #name : #MDLCardWidget, - #superclass : #MDLHighLevelWidget, - #instVars : [ - 'componentOrBlocks', - 'cardActions' - ], - #category : 'Material-Design-Lite-Widgets-Cards' -} - -{ #category : #adding } -MDLCardWidget >> accentColorTitle: aString [ - self accentColorTitle: aString class: '' -] - -{ #category : #adding } -MDLCardWidget >> accentColorTitle: aString class: anotherString [ - | classes | - classes := String - streamContents: [ :stream | - stream - nextPutAll: 'mdl-color--accent'; - space; - nextPutAll: 'mdl-color-text--accent-contrast'. - anotherString - ifNotEmpty: [ :string | - stream - space; - nextPutAll: string ] ]. - self title: aString class: classes -] - -{ #category : #options } -MDLCardWidget >> actionsBordered [ - self cardActions beBordered -] - -{ #category : #adding } -MDLCardWidget >> addAction: aComponentOrBlock [ - self cardActions addComponentOrBlock: aComponentOrBlock -] - -{ #category : #adding } -MDLCardWidget >> addComponentOrBlock: aComponentOrBlock [ - componentOrBlocks add: aComponentOrBlock -] - -{ #category : #adding } -MDLCardWidget >> addMedia: aBlock [ - self addComponentOrBlock: (MDLCardMediaWidget newWith: aBlock) -] - -{ #category : #adding } -MDLCardWidget >> addTextContainer: aString [ - self addComponentOrBlock: (MDLCardTextContainerWidget newWithContent: aString) -] - -{ #category : #adding } -MDLCardWidget >> addTextContainer: anObject class: cssClasses [ - self - addComponentOrBlock: (MDLCardTextContainerWidget newWithContent: anObject class: cssClasses) -] - -{ #category : #accessing } -MDLCardWidget >> cardActions [ - ^ cardActions - ifNil: [ cardActions := MDLCardActionsWidget new. - self addComponentOrBlock: cardActions. - ^ cardActions ] -] - -{ #category : #initialization } -MDLCardWidget >> initialize [ - super initialize. - componentOrBlocks := OrderedCollection new. - self class: 'mdl-card-widget' -] - -{ #category : #adding } -MDLCardWidget >> primaryColorTitle: aString [ - self primaryColorTitle: aString class: '' -] - -{ #category : #adding } -MDLCardWidget >> primaryColorTitle: aString class: anotherString [ - | classes | - classes := String - streamContents: [ :stream | - stream - nextPutAll: 'mdl-color--primary'; - space; - nextPutAll: 'mdl-color-text--primary-contrast'. - anotherString - ifNotEmpty: [ :string | - stream - space; - nextPutAll: string ] ]. - self title: aString class: classes -] - -{ #category : #rendering } -MDLCardWidget >> renderContentOn: html [ - | card | - card := html mdlCard. - self addPropertiesToBrush: card. - card with: [ self renderInnerWidgetsOn: html ] -] - -{ #category : #rendering } -MDLCardWidget >> renderInnerWidgetsOn: html [ - componentOrBlocks - do: [ :aComponentOrBlock | - aComponentOrBlock isBlock - ifTrue: [ aComponentOrBlock cull: html ] - ifFalse: [ html render: aComponentOrBlock ] ] -] - -{ #category : #accessing } -MDLCardWidget >> shadow: aNumber [ - "aNumber must be between 2 and 24" - - self propertiesAt: #shadow: put: (Array with: aNumber) -] - -{ #category : #adding } -MDLCardWidget >> title: aString [ - self title: aString level: 2 -] - -{ #category : #adding } -MDLCardWidget >> title: aString class: cssClasses [ - self title: aString level: 2 class: cssClasses -] - -{ #category : #adding } -MDLCardWidget >> title: aString level: aNumber [ - self title: aString level: aNumber class: '' -] - -{ #category : #adding } -MDLCardWidget >> title: aString level: aNumber class: cssClasses [ - self addComponentOrBlock: (MDLCardTitle newWithTitle: aString level: aNumber class: cssClasses) -] +" +High level widget to render a card +" +Class { + #name : #MDLCardWidget, + #superclass : #MDLHighLevelWidget, + #instVars : [ + 'componentOrBlocks', + 'cardActions' + ], + #category : 'Material-Design-Lite-Widgets-Cards' +} + +{ #category : #adding } +MDLCardWidget >> accentColorTitle: aString [ + self accentColorTitle: aString class: '' +] + +{ #category : #adding } +MDLCardWidget >> accentColorTitle: aString class: anotherString [ + | classes | + classes := String + streamContents: [ :stream | + stream + nextPutAll: 'mdl-color--accent'; + space; + nextPutAll: 'mdl-color-text--accent-contrast'. + anotherString + ifNotEmpty: [ :string | + stream + space; + nextPutAll: string ] ]. + self title: aString class: classes +] + +{ #category : #options } +MDLCardWidget >> actionsBordered [ + self cardActions beBordered +] + +{ #category : #adding } +MDLCardWidget >> addAction: aComponentOrBlock [ + self cardActions addComponentOrBlock: aComponentOrBlock +] + +{ #category : #adding } +MDLCardWidget >> addComponentOrBlock: aComponentOrBlock [ + componentOrBlocks add: aComponentOrBlock +] + +{ #category : #adding } +MDLCardWidget >> addMedia: aBlock [ + self addComponentOrBlock: (MDLCardMediaWidget newWith: aBlock) +] + +{ #category : #adding } +MDLCardWidget >> addTextContainer: aString [ + self addComponentOrBlock: (MDLCardTextContainerWidget newWithContent: aString) +] + +{ #category : #adding } +MDLCardWidget >> addTextContainer: anObject class: cssClasses [ + self + addComponentOrBlock: (MDLCardTextContainerWidget newWithContent: anObject class: cssClasses) +] + +{ #category : #accessing } +MDLCardWidget >> cardActions [ + ^ cardActions + ifNil: [ cardActions := MDLCardActionsWidget new. + self addComponentOrBlock: cardActions. + ^ cardActions ] +] + +{ #category : #initialization } +MDLCardWidget >> initialize [ + super initialize. + componentOrBlocks := OrderedCollection new. + self class: 'mdl-card-widget' +] + +{ #category : #adding } +MDLCardWidget >> primaryColorTitle: aString [ + self primaryColorTitle: aString class: '' +] + +{ #category : #adding } +MDLCardWidget >> primaryColorTitle: aString class: anotherString [ + | classes | + classes := String + streamContents: [ :stream | + stream + nextPutAll: 'mdl-color--primary'; + space; + nextPutAll: 'mdl-color-text--primary-contrast'. + anotherString + ifNotEmpty: [ :string | + stream + space; + nextPutAll: string ] ]. + self title: aString class: classes +] + +{ #category : #rendering } +MDLCardWidget >> renderContentOn: html [ + | card | + card := html mdlCard. + self addPropertiesToBrush: card. + card with: [ self renderInnerWidgetsOn: html ] +] + +{ #category : #rendering } +MDLCardWidget >> renderInnerWidgetsOn: html [ + componentOrBlocks + do: [ :aComponentOrBlock | + aComponentOrBlock isBlock + ifTrue: [ aComponentOrBlock cull: html ] + ifFalse: [ html render: aComponentOrBlock ] ] +] + +{ #category : #accessing } +MDLCardWidget >> shadow: aNumber [ + "aNumber must be between 2 and 24" + + self propertiesAt: #shadow: put: (Array with: aNumber) +] + +{ #category : #adding } +MDLCardWidget >> title: aString [ + self title: aString level: 2 +] + +{ #category : #adding } +MDLCardWidget >> title: aString class: cssClasses [ + self title: aString level: 2 class: cssClasses +] + +{ #category : #adding } +MDLCardWidget >> title: aString level: aNumber [ + self title: aString level: aNumber class: '' +] + +{ #category : #adding } +MDLCardWidget >> title: aString level: aNumber class: cssClasses [ + self addComponentOrBlock: (MDLCardTitle newWithTitle: aString level: aNumber class: cssClasses) +] diff --git a/src/Material-Design-Lite-Widgets/MDLContentCenterer.class.st b/src/Material-Design-Lite-Widgets/MDLContentCenterer.class.st index 54490a2f..9f6b2866 100644 --- a/src/Material-Design-Lite-Widgets/MDLContentCenterer.class.st +++ b/src/Material-Design-Lite-Widgets/MDLContentCenterer.class.st @@ -1,70 +1,70 @@ -" -Just a widget that allow to center a component and specify its size -" -Class { - #name : #MDLContentCenterer, - #superclass : #WAComponent, - #instVars : [ - 'component', - 'desktopSize', - 'tabletSize', - 'phoneSize' - ], - #category : 'Material-Design-Lite-Widgets' -} - -{ #category : #accessing } -MDLContentCenterer >> component [ - ^ component -] - -{ #category : #accessing } -MDLContentCenterer >> component: anObject [ - component := anObject -] - -{ #category : #accessing } -MDLContentCenterer >> desktopSize [ - ^ desktopSize -] - -{ #category : #accessing } -MDLContentCenterer >> desktopSize: anObject [ - desktopSize := anObject -] - -{ #category : #accessing } -MDLContentCenterer >> phoneSize [ - ^ phoneSize -] - -{ #category : #accessing } -MDLContentCenterer >> phoneSize: anObject [ - phoneSize := anObject -] - -{ #category : #rendering } -MDLContentCenterer >> renderContentOn: html [ - html mdlGrid: [ - html mdlLayoutSpacer. - html mdlCellDesktop: desktopSize tablet: tabletSize phone: phoneSize with: component. - html mdlLayoutSpacer ]. - super renderContentOn: html -] - -{ #category : #accessing } -MDLContentCenterer >> size: anObject [ - self desktopSize: anObject. - self phoneSize: anObject. - self tabletSize: anObject -] - -{ #category : #accessing } -MDLContentCenterer >> tabletSize [ - ^ tabletSize -] - -{ #category : #accessing } -MDLContentCenterer >> tabletSize: anObject [ - tabletSize := anObject -] +" +Just a widget that allow to center a component and specify its size +" +Class { + #name : #MDLContentCenterer, + #superclass : #WAComponent, + #instVars : [ + 'component', + 'desktopSize', + 'tabletSize', + 'phoneSize' + ], + #category : 'Material-Design-Lite-Widgets' +} + +{ #category : #accessing } +MDLContentCenterer >> component [ + ^ component +] + +{ #category : #accessing } +MDLContentCenterer >> component: anObject [ + component := anObject +] + +{ #category : #accessing } +MDLContentCenterer >> desktopSize [ + ^ desktopSize +] + +{ #category : #accessing } +MDLContentCenterer >> desktopSize: anObject [ + desktopSize := anObject +] + +{ #category : #accessing } +MDLContentCenterer >> phoneSize [ + ^ phoneSize +] + +{ #category : #accessing } +MDLContentCenterer >> phoneSize: anObject [ + phoneSize := anObject +] + +{ #category : #rendering } +MDLContentCenterer >> renderContentOn: html [ + html mdlGrid: [ + html mdlLayoutSpacer. + html mdlCellDesktop: desktopSize tablet: tabletSize phone: phoneSize with: component. + html mdlLayoutSpacer ]. + super renderContentOn: html +] + +{ #category : #accessing } +MDLContentCenterer >> size: anObject [ + self desktopSize: anObject. + self phoneSize: anObject. + self tabletSize: anObject +] + +{ #category : #accessing } +MDLContentCenterer >> tabletSize [ + ^ tabletSize +] + +{ #category : #accessing } +MDLContentCenterer >> tabletSize: anObject [ + tabletSize := anObject +] diff --git a/src/Material-Design-Lite-Widgets/MDLDatePicker.class.st b/src/Material-Design-Lite-Widgets/MDLDatePicker.class.st index c3e05c72..f22e7e9b 100644 --- a/src/Material-Design-Lite-Widgets/MDLDatePicker.class.st +++ b/src/Material-Design-Lite-Widgets/MDLDatePicker.class.st @@ -1,26 +1,26 @@ -" -I am a date picker embebded in a MDLCard for a better display. -" -Class { - #name : #MDLDatePicker, - #superclass : #MDLFlatDatePicker, - #category : #'Material-Design-Lite-Widgets-Calendar' -} - -{ #category : #accessing } -MDLDatePicker >> containerClass [ - ^ 'mdl-calendar-card' -] - -{ #category : #rendering } -MDLDatePicker >> renderCalendarOn: html [ - html - render: - (MDLCardWidget new - shadow: 2; - class: 'mdl-calendar-widget'; - addProperties: properties; - primaryColorTitle: self calendar printDateForHeader; - addTextContainer: [ self renderCalendarContentOn: html ]; - yourself) -] +" +I am a date picker embebded in a MDLCard for a better display. +" +Class { + #name : #MDLDatePicker, + #superclass : #MDLFlatDatePicker, + #category : #'Material-Design-Lite-Widgets-Calendar' +} + +{ #category : #accessing } +MDLDatePicker >> containerClass [ + ^ 'mdl-calendar-card' +] + +{ #category : #rendering } +MDLDatePicker >> renderCalendarOn: html [ + html + render: + (MDLCardWidget new + shadow: 2; + class: 'mdl-calendar-widget'; + addProperties: properties; + primaryColorTitle: self calendar printDateForHeader; + addTextContainer: [ self renderCalendarContentOn: html ]; + yourself) +] diff --git a/src/Material-Design-Lite-Widgets/MDLDialogWidget.class.st b/src/Material-Design-Lite-Widgets/MDLDialogWidget.class.st index 874d2478..181104bd 100644 --- a/src/Material-Design-Lite-Widgets/MDLDialogWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLDialogWidget.class.st @@ -1,176 +1,176 @@ -" -I represent a dialog widget -" -Class { - #name : #MDLDialogWidget, - #superclass : #MDLWidget, - #instVars : [ - 'title', - 'content', - 'actions', - 'buttonName', - 'closeButtonName', - 'buttonBrush', - 'dialogBrush' - ], - #category : 'Material-Design-Lite-Widgets-Dialog' -} - -{ #category : #'instance creation' } -MDLDialogWidget class >> content: aBlock actions: aSecondBlock buttonName: aString [ - ^ (self content: aBlock buttonName: aString) - actions: aSecondBlock; - yourself -] - -{ #category : #'instance creation' } -MDLDialogWidget class >> content: aBlock actions: aSecondBlock buttonName: aString closeButtonName: aSecondString [ - ^ (self new content: aBlock actions: aSecondBlock buttonName: aString) - closeButtonName: aSecondString; - yourself -] - -{ #category : #'instance creation' } -MDLDialogWidget class >> content: aBlock actions: aSecondBlock closeButtonName: aString [ - ^ (self content: aBlock buttonName: aString) - closeButtonName: aSecondBlock; - yourself -] - -{ #category : #'instance creation' } -MDLDialogWidget class >> content: aBlock buttonName: aString [ - ^ self new - content: aBlock; - buttonName: aString; - yourself -] - -{ #category : #'instance creation' } -MDLDialogWidget class >> title: aString content: aBlock actions: aSecondBlock buttonName: aSecondString [ - ^ (self content: aBlock actions: aSecondBlock buttonName: aSecondString) - title: aString; - yourself -] - -{ #category : #'instance creation' } -MDLDialogWidget class >> title: aString content: aBlock actions: aSecondBlock buttonName: aSecondString closeButtonName: aThirdString [ - ^ (self title: aString content: aBlock actions: aSecondBlock buttonName: aSecondString) - closeButtonName: aThirdString; - yourself -] - -{ #category : #'instance creation' } -MDLDialogWidget class >> title: aString content: aBlock buttonName: aSecondString [ - ^ (self content: aBlock buttonName: aSecondString) - title: aString; - yourself -] - -{ #category : #'instance creation' } -MDLDialogWidget class >> title: aString content: aBlock buttonName: aSecondString closeButtonName: aThirdString [ - ^ (self title: aString content: aBlock buttonName: aSecondString) - closeButtonName: aThirdString; - yourself -] - -{ #category : #accessing } -MDLDialogWidget >> actions [ - ^ actions -] - -{ #category : #accessing } -MDLDialogWidget >> actions: anObject [ - actions := anObject -] - -{ #category : #accessing } -MDLDialogWidget >> buttonBrush [ - ^ buttonBrush -] - -{ #category : #accessing } -MDLDialogWidget >> buttonBrush: anObject [ - buttonBrush := anObject -] - -{ #category : #accessing } -MDLDialogWidget >> buttonName [ - ^ buttonName -] - -{ #category : #accessing } -MDLDialogWidget >> buttonName: anObject [ - buttonName := anObject -] - -{ #category : #accessing } -MDLDialogWidget >> closeButtonName [ - ^ closeButtonName -] - -{ #category : #accessing } -MDLDialogWidget >> closeButtonName: anObject [ - closeButtonName := anObject -] - -{ #category : #accessing } -MDLDialogWidget >> content [ - ^ content -] - -{ #category : #accessing } -MDLDialogWidget >> content: anObject [ - content := anObject -] - -{ #category : #accessing } -MDLDialogWidget >> dialogBrush [ - ^ dialogBrush -] - -{ #category : #accessing } -MDLDialogWidget >> dialogBrush: anObject [ - dialogBrush := anObject -] - -{ #category : #initialization } -MDLDialogWidget >> initialize [ - super initialize. - closeButtonName := 'Close'. - buttonBrush := MDLButton new. - dialogBrush := MDLDialog new -] - -{ #category : #rendering } -MDLDialogWidget >> renderContentOn: html [ - | closeButtonId | - self ensureId: html. - (html brush: self buttonBrush) - id: self id; - bePush; - raised; - rippleEffect; - with: self buttonName. - (html brush: self dialogBrush) - id: html nextId; - openButtonId: self id; - closeButtonId: (closeButtonId := html nextId); - with: [ self title ifNotNil: [ :t | html mdlDialogTitle: t ]. - html mdlDialogContent: self content. - html - mdlDialogActions: [ self actions ifNotNil: [ :acts | html render: acts ]. - html mdlButton - id: closeButtonId; - bePush; - with: self closeButtonName ] ] -] - -{ #category : #accessing } -MDLDialogWidget >> title [ - ^ title -] - -{ #category : #accessing } -MDLDialogWidget >> title: anObject [ - title := anObject -] +" +I represent a dialog widget +" +Class { + #name : #MDLDialogWidget, + #superclass : #MDLWidget, + #instVars : [ + 'title', + 'content', + 'actions', + 'buttonName', + 'closeButtonName', + 'buttonBrush', + 'dialogBrush' + ], + #category : 'Material-Design-Lite-Widgets-Dialog' +} + +{ #category : #'instance creation' } +MDLDialogWidget class >> content: aBlock actions: aSecondBlock buttonName: aString [ + ^ (self content: aBlock buttonName: aString) + actions: aSecondBlock; + yourself +] + +{ #category : #'instance creation' } +MDLDialogWidget class >> content: aBlock actions: aSecondBlock buttonName: aString closeButtonName: aSecondString [ + ^ (self new content: aBlock actions: aSecondBlock buttonName: aString) + closeButtonName: aSecondString; + yourself +] + +{ #category : #'instance creation' } +MDLDialogWidget class >> content: aBlock actions: aSecondBlock closeButtonName: aString [ + ^ (self content: aBlock buttonName: aString) + closeButtonName: aSecondBlock; + yourself +] + +{ #category : #'instance creation' } +MDLDialogWidget class >> content: aBlock buttonName: aString [ + ^ self new + content: aBlock; + buttonName: aString; + yourself +] + +{ #category : #'instance creation' } +MDLDialogWidget class >> title: aString content: aBlock actions: aSecondBlock buttonName: aSecondString [ + ^ (self content: aBlock actions: aSecondBlock buttonName: aSecondString) + title: aString; + yourself +] + +{ #category : #'instance creation' } +MDLDialogWidget class >> title: aString content: aBlock actions: aSecondBlock buttonName: aSecondString closeButtonName: aThirdString [ + ^ (self title: aString content: aBlock actions: aSecondBlock buttonName: aSecondString) + closeButtonName: aThirdString; + yourself +] + +{ #category : #'instance creation' } +MDLDialogWidget class >> title: aString content: aBlock buttonName: aSecondString [ + ^ (self content: aBlock buttonName: aSecondString) + title: aString; + yourself +] + +{ #category : #'instance creation' } +MDLDialogWidget class >> title: aString content: aBlock buttonName: aSecondString closeButtonName: aThirdString [ + ^ (self title: aString content: aBlock buttonName: aSecondString) + closeButtonName: aThirdString; + yourself +] + +{ #category : #accessing } +MDLDialogWidget >> actions [ + ^ actions +] + +{ #category : #accessing } +MDLDialogWidget >> actions: anObject [ + actions := anObject +] + +{ #category : #accessing } +MDLDialogWidget >> buttonBrush [ + ^ buttonBrush +] + +{ #category : #accessing } +MDLDialogWidget >> buttonBrush: anObject [ + buttonBrush := anObject +] + +{ #category : #accessing } +MDLDialogWidget >> buttonName [ + ^ buttonName +] + +{ #category : #accessing } +MDLDialogWidget >> buttonName: anObject [ + buttonName := anObject +] + +{ #category : #accessing } +MDLDialogWidget >> closeButtonName [ + ^ closeButtonName +] + +{ #category : #accessing } +MDLDialogWidget >> closeButtonName: anObject [ + closeButtonName := anObject +] + +{ #category : #accessing } +MDLDialogWidget >> content [ + ^ content +] + +{ #category : #accessing } +MDLDialogWidget >> content: anObject [ + content := anObject +] + +{ #category : #accessing } +MDLDialogWidget >> dialogBrush [ + ^ dialogBrush +] + +{ #category : #accessing } +MDLDialogWidget >> dialogBrush: anObject [ + dialogBrush := anObject +] + +{ #category : #initialization } +MDLDialogWidget >> initialize [ + super initialize. + closeButtonName := 'Close'. + buttonBrush := MDLButton new. + dialogBrush := MDLDialog new +] + +{ #category : #rendering } +MDLDialogWidget >> renderContentOn: html [ + | closeButtonId | + self ensureId: html. + (html brush: self buttonBrush) + id: self id; + bePush; + raised; + rippleEffect; + with: self buttonName. + (html brush: self dialogBrush) + id: html nextId; + openButtonId: self id; + closeButtonId: (closeButtonId := html nextId); + with: [ self title ifNotNil: [ :t | html mdlDialogTitle: t ]. + html mdlDialogContent: self content. + html + mdlDialogActions: [ self actions ifNotNil: [ :acts | html render: acts ]. + html mdlButton + id: closeButtonId; + bePush; + with: self closeButtonName ] ] +] + +{ #category : #accessing } +MDLDialogWidget >> title [ + ^ title +] + +{ #category : #accessing } +MDLDialogWidget >> title: anObject [ + title := anObject +] diff --git a/src/Material-Design-Lite-Widgets/MDLExpansionPanel.class.st b/src/Material-Design-Lite-Widgets/MDLExpansionPanel.class.st index ee389f54..2ee66c87 100644 --- a/src/Material-Design-Lite-Widgets/MDLExpansionPanel.class.st +++ b/src/Material-Design-Lite-Widgets/MDLExpansionPanel.class.st @@ -1,162 +1,162 @@ -" -I am an expansion panel. - -Basically, I have a title, a description, an icon and I can be folded or expanded to show additional information. - -Though I provide default icons, one can set a different icon for when I am fold (#foldIcon:) or when I am expanded (#expandIcon:). - -One can set my initial state via #isExpanded: or #isFolded:. - -I can use different expansion strategies via #useDisplayNoneExpansionStrategy, #useAjaxExpansionStrategy. #useLazyExpansionStrategy. -See MDLExpansionStrategy subclasses for documentation about them. -My default strategy is MDLDisplayNoneStrategy. -" -Class { - #name : #MDLExpansionPanel, - #superclass : #MDLWidget, - #instVars : [ - 'title', - 'descriptions', - 'expandedBlock', - 'isExpanded', - 'shadow', - 'expansionStrategy' - ], - #category : #'Material-Design-Lite-Widgets-Expansion' -} - -{ #category : #accessing } -MDLExpansionPanel >> description: anObject [ - self descriptions: { anObject } -] - -{ #category : #accessing } -MDLExpansionPanel >> descriptions [ - ^ descriptions -] - -{ #category : #accessing } -MDLExpansionPanel >> descriptions: aCollection [ - descriptions := aCollection -] - -{ #category : #accessing } -MDLExpansionPanel >> expandedBlock [ - ^ expandedBlock -] - -{ #category : #accessing } -MDLExpansionPanel >> expandedBlock: anObject [ - expandedBlock := anObject -] - -{ #category : #accessing } -MDLExpansionPanel >> expansionStrategy [ - ^ expansionStrategy -] - -{ #category : #accessing } -MDLExpansionPanel >> expansionStrategy: anObject [ - expansionStrategy := anObject -] - -{ #category : #initialization } -MDLExpansionPanel >> initialize [ - super initialize. - self - title: ''; - description: ''; - shadow: 2; - isExpanded: false; - useHideExpansionStrategy -] - -{ #category : #accessing } -MDLExpansionPanel >> isExpanded [ - ^ isExpanded -] - -{ #category : #accessing } -MDLExpansionPanel >> isExpanded: anObject [ - isExpanded := anObject -] - -{ #category : #rendering } -MDLExpansionPanel >> isFolded [ - ^ self isExpanded not -] - -{ #category : #accessing } -MDLExpansionPanel >> isFolded: aBoolean [ - self isExpanded: aBoolean not -] - -{ #category : #rendering } -MDLExpansionPanel >> renderContentOn: html [ - self ensureId: html. - html mdlExpansionPanel - id: self id; - shadow: self shadow; - foldIf: self isFolded; - with: [ self renderExpansionPanelHeaderOn: html. - html mdlExpansionPanelContent: [ self renderExpansionPanelContentOn: html ] ] -] - -{ #category : #rendering } -MDLExpansionPanel >> renderExpansionPanelContentOn: html [ - self expansionStrategy renderExpansionPanel: self contentOn: html -] - -{ #category : #rendering } -MDLExpansionPanel >> renderExpansionPanelHeaderOn: html [ - | header | - header := html mdlExpansionPanelHeader - toggleExpansionOnClick; - yourself. - self expansionStrategy customize: header in: self on: html. - header - with: [ html mdlExpansionPanelHeaderTitle: self title. - self descriptions do: [ :description | html mdlExpansionPanelHeaderDescription: description ]. - html mdlExpansionPanelHeaderIcon ] -] - -{ #category : #accessing } -MDLExpansionPanel >> shadow [ - ^ shadow -] - -{ #category : #accessing } -MDLExpansionPanel >> shadow: anObject [ - shadow := anObject -] - -{ #category : #accessing } -MDLExpansionPanel >> title [ - ^ title -] - -{ #category : #accessing } -MDLExpansionPanel >> title: anObject [ - title := anObject -] - -{ #category : #toggling } -MDLExpansionPanel >> toggleExpansion [ - self isExpanded: self isExpanded not -] - -{ #category : #configuring } -MDLExpansionPanel >> useAjaxExpansionStrategy [ - self expansionStrategy: MDLAjaxExpansionStrategy new -] - -{ #category : #configuring } -MDLExpansionPanel >> useHideExpansionStrategy [ - "Default strategy." - self expansionStrategy: MDLHideExpansionStrategy new -] - -{ #category : #configuring } -MDLExpansionPanel >> useLazyExpansionStrategy [ - self expansionStrategy: MDLLazyExpansionStrategy new -] +" +I am an expansion panel. + +Basically, I have a title, a description, an icon and I can be folded or expanded to show additional information. + +Though I provide default icons, one can set a different icon for when I am fold (#foldIcon:) or when I am expanded (#expandIcon:). + +One can set my initial state via #isExpanded: or #isFolded:. + +I can use different expansion strategies via #useDisplayNoneExpansionStrategy, #useAjaxExpansionStrategy. #useLazyExpansionStrategy. +See MDLExpansionStrategy subclasses for documentation about them. +My default strategy is MDLDisplayNoneStrategy. +" +Class { + #name : #MDLExpansionPanel, + #superclass : #MDLWidget, + #instVars : [ + 'title', + 'descriptions', + 'expandedBlock', + 'isExpanded', + 'shadow', + 'expansionStrategy' + ], + #category : #'Material-Design-Lite-Widgets-Expansion' +} + +{ #category : #accessing } +MDLExpansionPanel >> description: anObject [ + self descriptions: { anObject } +] + +{ #category : #accessing } +MDLExpansionPanel >> descriptions [ + ^ descriptions +] + +{ #category : #accessing } +MDLExpansionPanel >> descriptions: aCollection [ + descriptions := aCollection +] + +{ #category : #accessing } +MDLExpansionPanel >> expandedBlock [ + ^ expandedBlock +] + +{ #category : #accessing } +MDLExpansionPanel >> expandedBlock: anObject [ + expandedBlock := anObject +] + +{ #category : #accessing } +MDLExpansionPanel >> expansionStrategy [ + ^ expansionStrategy +] + +{ #category : #accessing } +MDLExpansionPanel >> expansionStrategy: anObject [ + expansionStrategy := anObject +] + +{ #category : #initialization } +MDLExpansionPanel >> initialize [ + super initialize. + self + title: ''; + description: ''; + shadow: 2; + isExpanded: false; + useHideExpansionStrategy +] + +{ #category : #accessing } +MDLExpansionPanel >> isExpanded [ + ^ isExpanded +] + +{ #category : #accessing } +MDLExpansionPanel >> isExpanded: anObject [ + isExpanded := anObject +] + +{ #category : #rendering } +MDLExpansionPanel >> isFolded [ + ^ self isExpanded not +] + +{ #category : #accessing } +MDLExpansionPanel >> isFolded: aBoolean [ + self isExpanded: aBoolean not +] + +{ #category : #rendering } +MDLExpansionPanel >> renderContentOn: html [ + self ensureId: html. + html mdlExpansionPanel + id: self id; + shadow: self shadow; + foldIf: self isFolded; + with: [ self renderExpansionPanelHeaderOn: html. + html mdlExpansionPanelContent: [ self renderExpansionPanelContentOn: html ] ] +] + +{ #category : #rendering } +MDLExpansionPanel >> renderExpansionPanelContentOn: html [ + self expansionStrategy renderExpansionPanel: self contentOn: html +] + +{ #category : #rendering } +MDLExpansionPanel >> renderExpansionPanelHeaderOn: html [ + | header | + header := html mdlExpansionPanelHeader + toggleExpansionOnClick; + yourself. + self expansionStrategy customize: header in: self on: html. + header + with: [ html mdlExpansionPanelHeaderTitle: self title. + self descriptions do: [ :description | html mdlExpansionPanelHeaderDescription: description ]. + html mdlExpansionPanelHeaderIcon ] +] + +{ #category : #accessing } +MDLExpansionPanel >> shadow [ + ^ shadow +] + +{ #category : #accessing } +MDLExpansionPanel >> shadow: anObject [ + shadow := anObject +] + +{ #category : #accessing } +MDLExpansionPanel >> title [ + ^ title +] + +{ #category : #accessing } +MDLExpansionPanel >> title: anObject [ + title := anObject +] + +{ #category : #toggling } +MDLExpansionPanel >> toggleExpansion [ + self isExpanded: self isExpanded not +] + +{ #category : #configuring } +MDLExpansionPanel >> useAjaxExpansionStrategy [ + self expansionStrategy: MDLAjaxExpansionStrategy new +] + +{ #category : #configuring } +MDLExpansionPanel >> useHideExpansionStrategy [ + "Default strategy." + self expansionStrategy: MDLHideExpansionStrategy new +] + +{ #category : #configuring } +MDLExpansionPanel >> useLazyExpansionStrategy [ + self expansionStrategy: MDLLazyExpansionStrategy new +] diff --git a/src/Material-Design-Lite-Widgets/MDLExpansionStrategy.class.st b/src/Material-Design-Lite-Widgets/MDLExpansionStrategy.class.st index 20f70b0b..1f4e7d90 100644 --- a/src/Material-Design-Lite-Widgets/MDLExpansionStrategy.class.st +++ b/src/Material-Design-Lite-Widgets/MDLExpansionStrategy.class.st @@ -1,23 +1,23 @@ -" -I am an abstract expansion strategy, I define the minimal API such strategy should implement. -" -Class { - #name : #MDLExpansionStrategy, - #superclass : #Object, - #category : #'Material-Design-Lite-Widgets-Expansion' -} - -{ #category : #javascript } -MDLExpansionStrategy >> customize: anExpansionPanelHeader in: anExpansionPanel on: html [ - ^ self subclassResponsibility -] - -{ #category : #testing } -MDLExpansionStrategy >> isAjaxExpansionStrategy [ - ^ false -] - -{ #category : #rendering } -MDLExpansionStrategy >> renderExpansionPanel: anExpansionPanel contentOn: html [ - self subclassResponsibility -] +" +I am an abstract expansion strategy, I define the minimal API such strategy should implement. +" +Class { + #name : #MDLExpansionStrategy, + #superclass : #Object, + #category : #'Material-Design-Lite-Widgets-Expansion' +} + +{ #category : #javascript } +MDLExpansionStrategy >> customize: anExpansionPanelHeader in: anExpansionPanel on: html [ + ^ self subclassResponsibility +] + +{ #category : #testing } +MDLExpansionStrategy >> isAjaxExpansionStrategy [ + ^ false +] + +{ #category : #rendering } +MDLExpansionStrategy >> renderExpansionPanel: anExpansionPanel contentOn: html [ + self subclassResponsibility +] diff --git a/src/Material-Design-Lite-Widgets/MDLFlatDatePicker.class.st b/src/Material-Design-Lite-Widgets/MDLFlatDatePicker.class.st index 1996fd95..c319e367 100644 --- a/src/Material-Design-Lite-Widgets/MDLFlatDatePicker.class.st +++ b/src/Material-Design-Lite-Widgets/MDLFlatDatePicker.class.st @@ -1,336 +1,336 @@ -" -I am a component displaying a calendar to let the user pick a date. -" -Class { - #name : #MDLFlatDatePicker, - #superclass : #MDLHighLevelWidget, - #instVars : [ - 'daysList', - 'calendar', - 'callback', - 'onCompleteScript' - ], - #category : #'Material-Design-Lite-Widgets-Calendar' -} - -{ #category : #accessing } -MDLFlatDatePicker >> calendar [ - ^ calendar -] - -{ #category : #accessing } -MDLFlatDatePicker >> calendar: anObject [ - calendar := anObject -] - -{ #category : #accessing } -MDLFlatDatePicker >> callback: aOneArgBlock [ - aOneArgBlock argumentCount ~= 1 - ifTrue: [ ^ self error: '1 argument expected' ]. - callback := aOneArgBlock -] - -{ #category : #accessing } -MDLFlatDatePicker >> containerClass [ - ^ 'mdl-calendar' -] - -{ #category : #accessing } -MDLFlatDatePicker >> currentDate [ - ^ self calendar currentDate -] - -{ #category : #accessing } -MDLFlatDatePicker >> currentDate: aDate [ - self calendar currentDate: aDate -] - -{ #category : #accessing } -MDLFlatDatePicker >> daysList [ - ^ daysList -] - -{ #category : #'private-rendering' } -MDLFlatDatePicker >> displayDate: aDate on: html [ - html mdlButton - class: 'mdl-color-text--primary' if: (self isTodayAndNotSelected: aDate); - class: 'mdl-color-text--primary-contrast mdl-color--primary' if: (self selectedDateIs: aDate); - class: 'disabled' if: (self isInCurrentMonth: aDate) not; - rippleEffect; - icon; - onClick: (self jsUpdateDate: aDate on: html); - with: aDate dayOfMonth greaseString -] - -{ #category : #private } -MDLFlatDatePicker >> goToMonth: anObject [ - calendar goToMonth: anObject -] - -{ #category : #private } -MDLFlatDatePicker >> goToNextMonth [ - self calendar selectNextMonth -] - -{ #category : #private } -MDLFlatDatePicker >> goToNextYears [ - self calendar selectNextYears -] - -{ #category : #private } -MDLFlatDatePicker >> goToPreviousMonth [ - self calendar selectPreviousMonth -] - -{ #category : #private } -MDLFlatDatePicker >> goToPreviousYears [ - self calendar selectPreviousYears -] - -{ #category : #initialization } -MDLFlatDatePicker >> initialize [ - super initialize. - daysList := {'S' . 'M' . 'T' . 'W' . 'T' . 'F' . 'S'}. - calendar := MDLCalendar new. - onCompleteScript := '' -] - -{ #category : #testing } -MDLFlatDatePicker >> isInCurrentMonth: aDate [ - ^ aDate asMonth = self currentDate asMonth -] - -{ #category : #testing } -MDLFlatDatePicker >> isTodayAndNotSelected: aDate [ - ^ aDate = Date today and: [ aDate ~= self currentDate ] -] - -{ #category : #javascript } -MDLFlatDatePicker >> jsGoToMonth: aMonth on: html [ - ^ html jQuery ajax - callback: [ self goToMonth: aMonth ]; - onComplete: (self jsOnCompleteScriptOn: html) -] - -{ #category : #javascript } -MDLFlatDatePicker >> jsOnCompleteScript [ - ^ self onCompleteScript js -] - -{ #category : #javascript } -MDLFlatDatePicker >> jsOnCompleteScriptOn: html [ - ^ (html jQuery id: self id) load - html: [ :ajaxHtml | self renderCalendarOn: ajaxHtml ]; - onComplete: self jsOnCompleteScript -] - -{ #category : #javascript } -MDLFlatDatePicker >> jsUpdateDate: aDate on: html [ - ^ html jQuery ajax - callback: [ callback value: aDate. - self currentDate: aDate ]; - onComplete: (self jsOnCompleteScriptOn: html) -] - -{ #category : #accessing } -MDLFlatDatePicker >> onCompleteScript [ - ^ onCompleteScript -] - -{ #category : #accessing } -MDLFlatDatePicker >> onCompleteScript: anObject [ - onCompleteScript := anObject -] - -{ #category : #'private-rendering' } -MDLFlatDatePicker >> renderButtonNamed: aString renderingMethod: aSymbol on: html [ - html mdlButton - rippleEffect; - onClick: (((html jQuery id: self id) find: '.mdl-card__supporting-text') load html: [ :ajaxHtml | self perform: aSymbol with: ajaxHtml ]); - with: aString -] - -{ #category : #'private-rendering' } -MDLFlatDatePicker >> renderButtonWithIcon: anIcon action: aSymbol on: html [ - html - mdlCellDesktop: 2 - tablet: 1 - phone: 1 - with: [ html mdlButton - onClick: - (html jQuery ajax - callback: [ self perform: aSymbol ]; - onComplete: - ((html jQuery id: self id) load - html: [ :ajaxHtml | self renderCalendarOn: ajaxHtml ])); - rippleEffect; - style: 'color: rgba(0,0,0,0.7)'; - icon: anIcon ] -] - -{ #category : #rendering } -MDLFlatDatePicker >> renderCalendarBodyOn: html [ - html table - class: 'mdl-textfield--full-width'; - with: [ self renderDaysOn: html. - self renderWeeksOn: html ] -] - -{ #category : #rendering } -MDLFlatDatePicker >> renderCalendarContentOn: html [ - html mdlGrid - style: 'text-align: center; font-size: 14px; line-height:2; color: rgba(0,0,0,1)'; - with: [ - self renderCalendarHeaderOn: html. - html - mdlCellDesktop: 12 - tablet: 8 - phone: 4 - with: [ self renderCalendarBodyOn: html ] ] -] - -{ #category : #rendering } -MDLFlatDatePicker >> renderCalendarHeaderOn: html [ - self renderButtonWithIcon: 'navigate_before' action: #goToPreviousMonth on: html. - self renderCurrentMonthOn: html. - self renderButtonWithIcon: 'navigate_next' action: #goToNextMonth on: html -] - -{ #category : #rendering } -MDLFlatDatePicker >> renderCalendarOn: html [ - self renderCalendarTitleOn: html. - html div - class: 'mdl-card__supporting-text'; - with: [ self renderCalendarContentOn: html ] -] - -{ #category : #rendering } -MDLFlatDatePicker >> renderCalendarTitleOn: html [ - html div - mdlBackgroundColorPrimary; - class: 'mdl-calendar__title mdl-color-text--primary-contrast'; - with: [ html heading - level3; - with: self calendar printDateForHeader ] -] - -{ #category : #rendering } -MDLFlatDatePicker >> renderContentOn: html [ - self ensureId: html. - html div - id: self id; - class: self containerClass; - with: [ self renderCalendarOn: html ] -] - -{ #category : #rendering } -MDLFlatDatePicker >> renderCurrentMonthOn: html [ - html - mdlCellDesktop: 8 - tablet: 6 - phone: 2 - with: [ self - renderButtonNamed: self currentDate monthAbbreviation - renderingMethod: #renderMonthesOn: - on: html. - html space. - self - renderButtonNamed: self currentDate year greaseString - renderingMethod: #renderYearsOn: - on: html ] -] - -{ #category : #'private-rendering' } -MDLFlatDatePicker >> renderDate: aDate on: html [ - html tableData with: [ self displayDate: aDate on: html ] -] - -{ #category : #'private-rendering' } -MDLFlatDatePicker >> renderDaysOn: html [ - html tableColumnGroup: [ 1 to: 7 do: [ :i | html tableColumn width: '14,3%' ] ]. - html tableHead: [ html tableRow: [ self daysList do: [ :day | html tableHeading class: 'mdl-color-text--grey-600'; with: day ] ] ] -] - -{ #category : #'private-rendering' } -MDLFlatDatePicker >> renderMonthesOn: html [ - html mdlGrid - mdlTypographyTextCenter; - with: [ Date monthNames - do: [ :aString | - html mdlCell - class: 'month-cell'; - class: 'mdl-color-text--primary' if: aString = self currentDate monthName; - class: 'mdl-color-text--primary-contrast' if: aString = self currentDate monthName; - class: 'mdl-color--primary' if: aString = self currentDate monthName; - class: 'active' if: aString = self currentDate monthName; - onClick: (self jsGoToMonth: (Month indexOfMonth: aString) on: html); - desktopSize: 4; - with: aString ] ] -] - -{ #category : #'private-rendering' } -MDLFlatDatePicker >> renderWeeksOn: html [ - self currentDate asMonth weeks do: [ :aWeek | html tableRow: [ aWeek dates do: [ :aDate | self renderDate: aDate on: html ] ] ] -] - -{ #category : #'private-rendering' } -MDLFlatDatePicker >> renderYearsHeaderOn: html [ - self - renderYearsIntervalButtonWithIcon: 'navigate_before' - action: #goToPreviousYears - on: html. - html - mdlCellDesktop: 8 - tablet: 6 - phone: 2 - with: - (String - streamContents: [ :aStream | - aStream - nextPutAll: self calendar yearsInterval first greaseString; - nextPutAll: ' - '; - nextPutAll: self calendar yearsInterval last greaseString ]). - self - renderYearsIntervalButtonWithIcon: 'navigate_next' - action: #goToNextYears - on: html -] - -{ #category : #'private-rendering' } -MDLFlatDatePicker >> renderYearsIntervalButtonWithIcon: anIcon action: aSymbol on: html [ - html - mdlCellDesktop: 2 - tablet: 1 - phone: 1 - with: [ html mdlButton - onClick: (((html jQuery id: self id) find: '.mdl-card__supporting-text') load html: [ :ajaxHtml | self perform: aSymbol. self renderYearsOn: ajaxHtml ]); - rippleEffect; - style: 'color: rgba(0,0,0,0.7)'; - icon: anIcon ] -] - -{ #category : #'private-rendering' } -MDLFlatDatePicker >> renderYearsOn: html [ - html mdlGrid - mdlTypographyTextCenter; - with: [ self renderYearsHeaderOn: html. - self calendar yearsInterval - do: [ :aYear | - html mdlCell - class: 'year-cell'; - class: 'mdl-color-text--primary' if: aYear = self currentDate year; - class: 'mdl-color-text--primary-contrast' if: aYear = self currentDate year; - class: 'mdl-color--primary' if: aYear = self currentDate year; - class: 'active' if: aYear = self currentDate year; - onClick: - (html jQuery ajax - callback: [ self calendar goToYear: aYear ]; - onComplete: (self jsOnCompleteScriptOn: html)); - desktopSize: 4; - with: aYear greaseString ] ] -] - -{ #category : #testing } -MDLFlatDatePicker >> selectedDateIs: aDate [ - ^ aDate = self currentDate -] +" +I am a component displaying a calendar to let the user pick a date. +" +Class { + #name : #MDLFlatDatePicker, + #superclass : #MDLHighLevelWidget, + #instVars : [ + 'daysList', + 'calendar', + 'callback', + 'onCompleteScript' + ], + #category : #'Material-Design-Lite-Widgets-Calendar' +} + +{ #category : #accessing } +MDLFlatDatePicker >> calendar [ + ^ calendar +] + +{ #category : #accessing } +MDLFlatDatePicker >> calendar: anObject [ + calendar := anObject +] + +{ #category : #accessing } +MDLFlatDatePicker >> callback: aOneArgBlock [ + aOneArgBlock argumentCount ~= 1 + ifTrue: [ ^ self error: '1 argument expected' ]. + callback := aOneArgBlock +] + +{ #category : #accessing } +MDLFlatDatePicker >> containerClass [ + ^ 'mdl-calendar' +] + +{ #category : #accessing } +MDLFlatDatePicker >> currentDate [ + ^ self calendar currentDate +] + +{ #category : #accessing } +MDLFlatDatePicker >> currentDate: aDate [ + self calendar currentDate: aDate +] + +{ #category : #accessing } +MDLFlatDatePicker >> daysList [ + ^ daysList +] + +{ #category : #'private-rendering' } +MDLFlatDatePicker >> displayDate: aDate on: html [ + html mdlButton + class: 'mdl-color-text--primary' if: (self isTodayAndNotSelected: aDate); + class: 'mdl-color-text--primary-contrast mdl-color--primary' if: (self selectedDateIs: aDate); + class: 'disabled' if: (self isInCurrentMonth: aDate) not; + rippleEffect; + icon; + onClick: (self jsUpdateDate: aDate on: html); + with: aDate dayOfMonth greaseString +] + +{ #category : #private } +MDLFlatDatePicker >> goToMonth: anObject [ + calendar goToMonth: anObject +] + +{ #category : #private } +MDLFlatDatePicker >> goToNextMonth [ + self calendar selectNextMonth +] + +{ #category : #private } +MDLFlatDatePicker >> goToNextYears [ + self calendar selectNextYears +] + +{ #category : #private } +MDLFlatDatePicker >> goToPreviousMonth [ + self calendar selectPreviousMonth +] + +{ #category : #private } +MDLFlatDatePicker >> goToPreviousYears [ + self calendar selectPreviousYears +] + +{ #category : #initialization } +MDLFlatDatePicker >> initialize [ + super initialize. + daysList := {'S' . 'M' . 'T' . 'W' . 'T' . 'F' . 'S'}. + calendar := MDLCalendar new. + onCompleteScript := '' +] + +{ #category : #testing } +MDLFlatDatePicker >> isInCurrentMonth: aDate [ + ^ aDate asMonth = self currentDate asMonth +] + +{ #category : #testing } +MDLFlatDatePicker >> isTodayAndNotSelected: aDate [ + ^ aDate = Date today and: [ aDate ~= self currentDate ] +] + +{ #category : #javascript } +MDLFlatDatePicker >> jsGoToMonth: aMonth on: html [ + ^ html jQuery ajax + callback: [ self goToMonth: aMonth ]; + onComplete: (self jsOnCompleteScriptOn: html) +] + +{ #category : #javascript } +MDLFlatDatePicker >> jsOnCompleteScript [ + ^ self onCompleteScript js +] + +{ #category : #javascript } +MDLFlatDatePicker >> jsOnCompleteScriptOn: html [ + ^ (html jQuery id: self id) load + html: [ :ajaxHtml | self renderCalendarOn: ajaxHtml ]; + onComplete: self jsOnCompleteScript +] + +{ #category : #javascript } +MDLFlatDatePicker >> jsUpdateDate: aDate on: html [ + ^ html jQuery ajax + callback: [ callback value: aDate. + self currentDate: aDate ]; + onComplete: (self jsOnCompleteScriptOn: html) +] + +{ #category : #accessing } +MDLFlatDatePicker >> onCompleteScript [ + ^ onCompleteScript +] + +{ #category : #accessing } +MDLFlatDatePicker >> onCompleteScript: anObject [ + onCompleteScript := anObject +] + +{ #category : #'private-rendering' } +MDLFlatDatePicker >> renderButtonNamed: aString renderingMethod: aSymbol on: html [ + html mdlButton + rippleEffect; + onClick: (((html jQuery id: self id) find: '.mdl-card__supporting-text') load html: [ :ajaxHtml | self perform: aSymbol with: ajaxHtml ]); + with: aString +] + +{ #category : #'private-rendering' } +MDLFlatDatePicker >> renderButtonWithIcon: anIcon action: aSymbol on: html [ + html + mdlCellDesktop: 2 + tablet: 1 + phone: 1 + with: [ html mdlButton + onClick: + (html jQuery ajax + callback: [ self perform: aSymbol ]; + onComplete: + ((html jQuery id: self id) load + html: [ :ajaxHtml | self renderCalendarOn: ajaxHtml ])); + rippleEffect; + style: 'color: rgba(0,0,0,0.7)'; + icon: anIcon ] +] + +{ #category : #rendering } +MDLFlatDatePicker >> renderCalendarBodyOn: html [ + html table + class: 'mdl-textfield--full-width'; + with: [ self renderDaysOn: html. + self renderWeeksOn: html ] +] + +{ #category : #rendering } +MDLFlatDatePicker >> renderCalendarContentOn: html [ + html mdlGrid + style: 'text-align: center; font-size: 14px; line-height:2; color: rgba(0,0,0,1)'; + with: [ + self renderCalendarHeaderOn: html. + html + mdlCellDesktop: 12 + tablet: 8 + phone: 4 + with: [ self renderCalendarBodyOn: html ] ] +] + +{ #category : #rendering } +MDLFlatDatePicker >> renderCalendarHeaderOn: html [ + self renderButtonWithIcon: 'navigate_before' action: #goToPreviousMonth on: html. + self renderCurrentMonthOn: html. + self renderButtonWithIcon: 'navigate_next' action: #goToNextMonth on: html +] + +{ #category : #rendering } +MDLFlatDatePicker >> renderCalendarOn: html [ + self renderCalendarTitleOn: html. + html div + class: 'mdl-card__supporting-text'; + with: [ self renderCalendarContentOn: html ] +] + +{ #category : #rendering } +MDLFlatDatePicker >> renderCalendarTitleOn: html [ + html div + mdlBackgroundColorPrimary; + class: 'mdl-calendar__title mdl-color-text--primary-contrast'; + with: [ html heading + level3; + with: self calendar printDateForHeader ] +] + +{ #category : #rendering } +MDLFlatDatePicker >> renderContentOn: html [ + self ensureId: html. + html div + id: self id; + class: self containerClass; + with: [ self renderCalendarOn: html ] +] + +{ #category : #rendering } +MDLFlatDatePicker >> renderCurrentMonthOn: html [ + html + mdlCellDesktop: 8 + tablet: 6 + phone: 2 + with: [ self + renderButtonNamed: self currentDate monthAbbreviation + renderingMethod: #renderMonthesOn: + on: html. + html space. + self + renderButtonNamed: self currentDate year greaseString + renderingMethod: #renderYearsOn: + on: html ] +] + +{ #category : #'private-rendering' } +MDLFlatDatePicker >> renderDate: aDate on: html [ + html tableData with: [ self displayDate: aDate on: html ] +] + +{ #category : #'private-rendering' } +MDLFlatDatePicker >> renderDaysOn: html [ + html tableColumnGroup: [ 1 to: 7 do: [ :i | html tableColumn width: '14,3%' ] ]. + html tableHead: [ html tableRow: [ self daysList do: [ :day | html tableHeading class: 'mdl-color-text--grey-600'; with: day ] ] ] +] + +{ #category : #'private-rendering' } +MDLFlatDatePicker >> renderMonthesOn: html [ + html mdlGrid + mdlTypographyTextCenter; + with: [ Date monthNames + do: [ :aString | + html mdlCell + class: 'month-cell'; + class: 'mdl-color-text--primary' if: aString = self currentDate monthName; + class: 'mdl-color-text--primary-contrast' if: aString = self currentDate monthName; + class: 'mdl-color--primary' if: aString = self currentDate monthName; + class: 'active' if: aString = self currentDate monthName; + onClick: (self jsGoToMonth: (Month indexOfMonth: aString) on: html); + desktopSize: 4; + with: aString ] ] +] + +{ #category : #'private-rendering' } +MDLFlatDatePicker >> renderWeeksOn: html [ + self currentDate asMonth weeks do: [ :aWeek | html tableRow: [ aWeek dates do: [ :aDate | self renderDate: aDate on: html ] ] ] +] + +{ #category : #'private-rendering' } +MDLFlatDatePicker >> renderYearsHeaderOn: html [ + self + renderYearsIntervalButtonWithIcon: 'navigate_before' + action: #goToPreviousYears + on: html. + html + mdlCellDesktop: 8 + tablet: 6 + phone: 2 + with: + (String + streamContents: [ :aStream | + aStream + nextPutAll: self calendar yearsInterval first greaseString; + nextPutAll: ' - '; + nextPutAll: self calendar yearsInterval last greaseString ]). + self + renderYearsIntervalButtonWithIcon: 'navigate_next' + action: #goToNextYears + on: html +] + +{ #category : #'private-rendering' } +MDLFlatDatePicker >> renderYearsIntervalButtonWithIcon: anIcon action: aSymbol on: html [ + html + mdlCellDesktop: 2 + tablet: 1 + phone: 1 + with: [ html mdlButton + onClick: (((html jQuery id: self id) find: '.mdl-card__supporting-text') load html: [ :ajaxHtml | self perform: aSymbol. self renderYearsOn: ajaxHtml ]); + rippleEffect; + style: 'color: rgba(0,0,0,0.7)'; + icon: anIcon ] +] + +{ #category : #'private-rendering' } +MDLFlatDatePicker >> renderYearsOn: html [ + html mdlGrid + mdlTypographyTextCenter; + with: [ self renderYearsHeaderOn: html. + self calendar yearsInterval + do: [ :aYear | + html mdlCell + class: 'year-cell'; + class: 'mdl-color-text--primary' if: aYear = self currentDate year; + class: 'mdl-color-text--primary-contrast' if: aYear = self currentDate year; + class: 'mdl-color--primary' if: aYear = self currentDate year; + class: 'active' if: aYear = self currentDate year; + onClick: + (html jQuery ajax + callback: [ self calendar goToYear: aYear ]; + onComplete: (self jsOnCompleteScriptOn: html)); + desktopSize: 4; + with: aYear greaseString ] ] +] + +{ #category : #testing } +MDLFlatDatePicker >> selectedDateIs: aDate [ + ^ aDate = self currentDate +] diff --git a/src/Material-Design-Lite-Widgets/MDLFooter.class.st b/src/Material-Design-Lite-Widgets/MDLFooter.class.st index 0eaa1775..59803538 100644 --- a/src/Material-Design-Lite-Widgets/MDLFooter.class.st +++ b/src/Material-Design-Lite-Widgets/MDLFooter.class.st @@ -1,82 +1,82 @@ -" -I am a MDLFooter. -I'm divided in 3 rows : topSection middleSection bottomSection. - -Each section needs a collection of links to work, and a title. - -The links in the middle section will be displayed vertically , whereas the top and bottom sections will be displayed horizontally. (it's a choice, you can implement your own footer if you want to do it in an other way). - -The middle section can contain multiple Dropdown sections. - -Top and Bottom sections can receive only one section (it is still a choice). -" -Class { - #name : #MDLFooter, - #superclass : #MDLWidget, - #instVars : [ - 'topLeftSection', - 'topRightSection', - 'middleSection', - 'bottomSection' - ], - #category : #'Material-Design-Lite-Widgets-Footer' -} - -{ #category : #'public api' } -MDLFooter >> atBottomAddLinks: links [ - "Links must be formatted as following : (header -> #((label1->url1) . (label2 -> url2)))" - - bottomSection isNilSection - ifTrue: [ bottomSection := MDLFooterLinksSection new ]. - bottomSection := bottomSection - addLinksList: - (MDLMegaFooterLinksList new - addLinks: links; - yourself) -] - -{ #category : #'public api' } -MDLFooter >> atMiddleAddLinks: links [ - "Links must be formatted as following : #(header -> #( (label1->url1) . (label2 -> url2)))" - - | list | - middleSection isNilSection - ifTrue: [ middleSection := MDLFooterDropdownSection new ]. - list := links collect: [ :anAssociation | MDLMegaFooterLinksList new addLinks: anAssociation ]. - middleSection addLinksLists: list -] - -{ #category : #'public api' } -MDLFooter >> atTopLeftAddComponents: components [ - "Components must be an array of WAComponents (render: will be called on them)" - topLeftSection isNilSection - ifTrue: [ topLeftSection := MDLFooterComponentsSection new ]. - topLeftSection := topLeftSection addComponents: components -] - -{ #category : #'public api' } -MDLFooter >> atTopRightAddComponents: components [ - "Components must be an array of WAComponents (render: will be called on them)" - topRightSection isNilSection - ifTrue: [ topRightSection := MDLFooterComponentsSection new ]. - topRightSection := topRightSection addComponents: components -] - -{ #category : #initialization } -MDLFooter >> initialize [ - super initialize. - topLeftSection := MDLFooterNilSection new. - topRightSection := MDLFooterNilSection new. - middleSection := MDLFooterNilSection new. - bottomSection := MDLFooterNilSection new -] - -{ #category : #rendering } -MDLFooter >> renderContentOn: html [ - html mdlFooter: [ - html mdlFooterTopSection: [ - html mdlFooterLeftSection: [ topLeftSection renderSectionOn: html ]. - html mdlFooterRightSection: [ topRightSection renderSectionOn: html ] ]. - html mdlFooterMiddleSection: [ middleSection renderSectionOn: html ]. - html mdlFooterBottomSection: [ bottomSection renderSectionOn: html ] ] -] +" +I am a MDLFooter. +I'm divided in 3 rows : topSection middleSection bottomSection. + +Each section needs a collection of links to work, and a title. + +The links in the middle section will be displayed vertically , whereas the top and bottom sections will be displayed horizontally. (it's a choice, you can implement your own footer if you want to do it in an other way). + +The middle section can contain multiple Dropdown sections. + +Top and Bottom sections can receive only one section (it is still a choice). +" +Class { + #name : #MDLFooter, + #superclass : #MDLWidget, + #instVars : [ + 'topLeftSection', + 'topRightSection', + 'middleSection', + 'bottomSection' + ], + #category : #'Material-Design-Lite-Widgets-Footer' +} + +{ #category : #'public api' } +MDLFooter >> atBottomAddLinks: links [ + "Links must be formatted as following : (header -> #((label1->url1) . (label2 -> url2)))" + + bottomSection isNilSection + ifTrue: [ bottomSection := MDLFooterLinksSection new ]. + bottomSection := bottomSection + addLinksList: + (MDLMegaFooterLinksList new + addLinks: links; + yourself) +] + +{ #category : #'public api' } +MDLFooter >> atMiddleAddLinks: links [ + "Links must be formatted as following : #(header -> #( (label1->url1) . (label2 -> url2)))" + + | list | + middleSection isNilSection + ifTrue: [ middleSection := MDLFooterDropdownSection new ]. + list := links collect: [ :anAssociation | MDLMegaFooterLinksList new addLinks: anAssociation ]. + middleSection addLinksLists: list +] + +{ #category : #'public api' } +MDLFooter >> atTopLeftAddComponents: components [ + "Components must be an array of WAComponents (render: will be called on them)" + topLeftSection isNilSection + ifTrue: [ topLeftSection := MDLFooterComponentsSection new ]. + topLeftSection := topLeftSection addComponents: components +] + +{ #category : #'public api' } +MDLFooter >> atTopRightAddComponents: components [ + "Components must be an array of WAComponents (render: will be called on them)" + topRightSection isNilSection + ifTrue: [ topRightSection := MDLFooterComponentsSection new ]. + topRightSection := topRightSection addComponents: components +] + +{ #category : #initialization } +MDLFooter >> initialize [ + super initialize. + topLeftSection := MDLFooterNilSection new. + topRightSection := MDLFooterNilSection new. + middleSection := MDLFooterNilSection new. + bottomSection := MDLFooterNilSection new +] + +{ #category : #rendering } +MDLFooter >> renderContentOn: html [ + html mdlFooter: [ + html mdlFooterTopSection: [ + html mdlFooterLeftSection: [ topLeftSection renderSectionOn: html ]. + html mdlFooterRightSection: [ topRightSection renderSectionOn: html ] ]. + html mdlFooterMiddleSection: [ middleSection renderSectionOn: html ]. + html mdlFooterBottomSection: [ bottomSection renderSectionOn: html ] ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLFooterAbstractSection.class.st b/src/Material-Design-Lite-Widgets/MDLFooterAbstractSection.class.st index 59bb096a..78d97682 100644 --- a/src/Material-Design-Lite-Widgets/MDLFooterAbstractSection.class.st +++ b/src/Material-Design-Lite-Widgets/MDLFooterAbstractSection.class.st @@ -1,15 +1,15 @@ -Class { - #name : #MDLFooterAbstractSection, - #superclass : #Object, - #category : 'Material-Design-Lite-Widgets-Footer' -} - -{ #category : #testing } -MDLFooterAbstractSection >> isNilSection [ - ^ false -] - -{ #category : #rendering } -MDLFooterAbstractSection >> renderSectionOn: html [ - self subclassResponsibility -] +Class { + #name : #MDLFooterAbstractSection, + #superclass : #Object, + #category : 'Material-Design-Lite-Widgets-Footer' +} + +{ #category : #testing } +MDLFooterAbstractSection >> isNilSection [ + ^ false +] + +{ #category : #rendering } +MDLFooterAbstractSection >> renderSectionOn: html [ + self subclassResponsibility +] diff --git a/src/Material-Design-Lite-Widgets/MDLFooterComponentsSection.class.st b/src/Material-Design-Lite-Widgets/MDLFooterComponentsSection.class.st index 4fb82041..2a6fc602 100644 --- a/src/Material-Design-Lite-Widgets/MDLFooterComponentsSection.class.st +++ b/src/Material-Design-Lite-Widgets/MDLFooterComponentsSection.class.st @@ -1,18 +1,18 @@ -Class { - #name : #MDLFooterComponentsSection, - #superclass : #MDLFooterAbstractSection, - #instVars : [ - 'components' - ], - #category : 'Material-Design-Lite-Widgets-Footer' -} - -{ #category : #adding } -MDLFooterComponentsSection >> addComponents: aComponentsCollection [ - components := aComponentsCollection -] - -{ #category : #rendering } -MDLFooterComponentsSection >> renderSectionOn: html [ - components do: [ :aComponent | html render: aComponent ] -] +Class { + #name : #MDLFooterComponentsSection, + #superclass : #MDLFooterAbstractSection, + #instVars : [ + 'components' + ], + #category : 'Material-Design-Lite-Widgets-Footer' +} + +{ #category : #adding } +MDLFooterComponentsSection >> addComponents: aComponentsCollection [ + components := aComponentsCollection +] + +{ #category : #rendering } +MDLFooterComponentsSection >> renderSectionOn: html [ + components do: [ :aComponent | html render: aComponent ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLFooterDropdownSection.class.st b/src/Material-Design-Lite-Widgets/MDLFooterDropdownSection.class.st index 371cfc0c..a3292b76 100644 --- a/src/Material-Design-Lite-Widgets/MDLFooterDropdownSection.class.st +++ b/src/Material-Design-Lite-Widgets/MDLFooterDropdownSection.class.st @@ -1,24 +1,24 @@ -Class { - #name : #MDLFooterDropdownSection, - #superclass : #MDLFooterAbstractSection, - #instVars : [ - 'linksLists' - ], - #category : 'Material-Design-Lite-Widgets-Footer' -} - -{ #category : #adding } -MDLFooterDropdownSection >> addLinksLists: lists [ - linksLists addAll: lists -] - -{ #category : #initialization } -MDLFooterDropdownSection >> initialize [ - super initialize. - linksLists := OrderedCollection new -] - -{ #category : #rendering } -MDLFooterDropdownSection >> renderSectionOn: html [ - linksLists do: [ :aList | html mdlFooterDropdownSection: [ aList renderLinksWithHeaderOn: html ] ]. -] +Class { + #name : #MDLFooterDropdownSection, + #superclass : #MDLFooterAbstractSection, + #instVars : [ + 'linksLists' + ], + #category : 'Material-Design-Lite-Widgets-Footer' +} + +{ #category : #adding } +MDLFooterDropdownSection >> addLinksLists: lists [ + linksLists addAll: lists +] + +{ #category : #initialization } +MDLFooterDropdownSection >> initialize [ + super initialize. + linksLists := OrderedCollection new +] + +{ #category : #rendering } +MDLFooterDropdownSection >> renderSectionOn: html [ + linksLists do: [ :aList | html mdlFooterDropdownSection: [ aList renderLinksWithHeaderOn: html ] ]. +] diff --git a/src/Material-Design-Lite-Widgets/MDLFooterLinksSection.class.st b/src/Material-Design-Lite-Widgets/MDLFooterLinksSection.class.st index 985b4749..955b2d4b 100644 --- a/src/Material-Design-Lite-Widgets/MDLFooterLinksSection.class.st +++ b/src/Material-Design-Lite-Widgets/MDLFooterLinksSection.class.st @@ -1,24 +1,24 @@ -Class { - #name : #MDLFooterLinksSection, - #superclass : #MDLFooterAbstractSection, - #instVars : [ - 'linksList' - ], - #category : 'Material-Design-Lite-Widgets-Footer' -} - -{ #category : #adding } -MDLFooterLinksSection >> addLinksList: aLinksList [ - linksList := aLinksList -] - -{ #category : #initialization } -MDLFooterLinksSection >> initialize [ - super initialize. - linksList := MDLMegaFooterLinksList new -] - -{ #category : #rendering } -MDLFooterLinksSection >> renderSectionOn: html [ - linksList renderLinksWithLogoOn: html -] +Class { + #name : #MDLFooterLinksSection, + #superclass : #MDLFooterAbstractSection, + #instVars : [ + 'linksList' + ], + #category : 'Material-Design-Lite-Widgets-Footer' +} + +{ #category : #adding } +MDLFooterLinksSection >> addLinksList: aLinksList [ + linksList := aLinksList +] + +{ #category : #initialization } +MDLFooterLinksSection >> initialize [ + super initialize. + linksList := MDLMegaFooterLinksList new +] + +{ #category : #rendering } +MDLFooterLinksSection >> renderSectionOn: html [ + linksList renderLinksWithLogoOn: html +] diff --git a/src/Material-Design-Lite-Widgets/MDLFooterNilSection.class.st b/src/Material-Design-Lite-Widgets/MDLFooterNilSection.class.st index da6a3270..3cea7a8b 100644 --- a/src/Material-Design-Lite-Widgets/MDLFooterNilSection.class.st +++ b/src/Material-Design-Lite-Widgets/MDLFooterNilSection.class.st @@ -1,20 +1,20 @@ -Class { - #name : #MDLFooterNilSection, - #superclass : #MDLFooterAbstractSection, - #category : 'Material-Design-Lite-Widgets-Footer' -} - -{ #category : #adding } -MDLFooterNilSection >> addLinks: someLinks [ - self shouldNotImplement -] - -{ #category : #testing } -MDLFooterNilSection >> isNilSection [ - ^ true -] - -{ #category : #testing } -MDLFooterNilSection >> renderSectionOn: html [ - "do nothing" -] +Class { + #name : #MDLFooterNilSection, + #superclass : #MDLFooterAbstractSection, + #category : 'Material-Design-Lite-Widgets-Footer' +} + +{ #category : #adding } +MDLFooterNilSection >> addLinks: someLinks [ + self shouldNotImplement +] + +{ #category : #testing } +MDLFooterNilSection >> isNilSection [ + ^ true +] + +{ #category : #testing } +MDLFooterNilSection >> renderSectionOn: html [ + "do nothing" +] diff --git a/src/Material-Design-Lite-Widgets/MDLHideExpansionStrategy.class.st b/src/Material-Design-Lite-Widgets/MDLHideExpansionStrategy.class.st index 76760f5c..9bb772df 100644 --- a/src/Material-Design-Lite-Widgets/MDLHideExpansionStrategy.class.st +++ b/src/Material-Design-Lite-Widgets/MDLHideExpansionStrategy.class.st @@ -1,22 +1,22 @@ -" -I am an expansion strategy that uses CSS properties to hide the expansion panel content when it should not be shown. - -I also use a little of javascript to update the icon according to the state of the panel. -" -Class { - #name : #MDLHideExpansionStrategy, - #superclass : #MDLExpansionStrategy, - #category : #'Material-Design-Lite-Widgets-Expansion' -} - -{ #category : #javascript } -MDLHideExpansionStrategy >> customize: anExpansionPanelHeader in: anExpansionPanel on: html [ - "Do nothing here." - - -] - -{ #category : #rendering } -MDLHideExpansionStrategy >> renderExpansionPanel: anExpansionPanel contentOn: html [ - anExpansionPanel expandedBlock value: html -] +" +I am an expansion strategy that uses CSS properties to hide the expansion panel content when it should not be shown. + +I also use a little of javascript to update the icon according to the state of the panel. +" +Class { + #name : #MDLHideExpansionStrategy, + #superclass : #MDLExpansionStrategy, + #category : #'Material-Design-Lite-Widgets-Expansion' +} + +{ #category : #javascript } +MDLHideExpansionStrategy >> customize: anExpansionPanelHeader in: anExpansionPanel on: html [ + "Do nothing here." + + +] + +{ #category : #rendering } +MDLHideExpansionStrategy >> renderExpansionPanel: anExpansionPanel contentOn: html [ + anExpansionPanel expandedBlock value: html +] diff --git a/src/Material-Design-Lite-Widgets/MDLHighLevelWidget.class.st b/src/Material-Design-Lite-Widgets/MDLHighLevelWidget.class.st index a08067c1..a16b1a92 100644 --- a/src/Material-Design-Lite-Widgets/MDLHighLevelWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLHighLevelWidget.class.st @@ -1,114 +1,114 @@ -" -I represent an abstract class for high level widgets. - -Interesting point is that I have properties through a Dictionary which allow me to add some behaviours. My properties should have a selector as key and an array of parameters as value. -" -Class { - #name : #MDLHighLevelWidget, - #superclass : #MDLWidget, - #instVars : [ - 'properties' - ], - #category : #'Material-Design-Lite-Widgets' -} - -{ #category : #accessing } -MDLHighLevelWidget >> addProperties: aDictionary [ - properties addAll: aDictionary -] - -{ #category : #actions } -MDLHighLevelWidget >> addPropertiesToBrush: aBrush [ - self properties keysAndValuesDo: [ :aSymbol :arguments | aBrush perform: aSymbol withArguments: arguments ] -] - -{ #category : #accessing } -MDLHighLevelWidget >> class: aString [ - | stringToAdd | - aString isEmptyOrNil ifTrue: [ ^ self ]. - - stringToAdd := self - propertiesAt: #class: - ifPresent: [ :oldClasses | - stringToAdd := String - streamContents: [ :aStream | - aStream - nextPutAll: oldClasses anyOne; - space; - nextPutAll: aString ] ] - ifAbsent: [ aString ]. - - self propertiesAt: #class: put: (Array with: stringToAdd) -] - -{ #category : #accessing } -MDLHighLevelWidget >> htmlClass [ - "htmlClass because it can cause problems to have a #class method in objects." - - ^ self propertiesAt: #class ifPresent: [ :array | array anyOne ] ifAbsent: [ nil ] -] - -{ #category : #accessing } -MDLHighLevelWidget >> id [ - ^ self propertiesAt: #id: ifPresent: [ :array | array anyOne ] ifAbsent: [ nil ] -] - -{ #category : #accessing } -MDLHighLevelWidget >> id: aString [ - self propertiesAt: #id: put: (Array with: aString) -] - -{ #category : #initialization } -MDLHighLevelWidget >> initialize [ - super initialize. - properties := OrderedDictionary new -] - -{ #category : #accessing } -MDLHighLevelWidget >> onClick: anObject [ - self propertiesAt: #onClick: put: (Array with: anObject) -] - -{ #category : #accessing } -MDLHighLevelWidget >> properties [ - ^ properties -] - -{ #category : #accessing } -MDLHighLevelWidget >> propertiesAt: aString [ - ^ self properties at: aString -] - -{ #category : #accessing } -MDLHighLevelWidget >> propertiesAt: aString ifAbsent: aBlock [ - ^ self properties at: aString ifAbsent: aBlock -] - -{ #category : #accessing } -MDLHighLevelWidget >> propertiesAt: aString ifPresent: aBlock ifAbsent: anotherBlock [ - ^ self properties at: aString ifPresent: aBlock ifAbsent: anotherBlock -] - -{ #category : #accessing } -MDLHighLevelWidget >> propertiesAt: aString put: anArray [ - self properties at: aString put: anArray -] - -{ #category : #accessing } -MDLHighLevelWidget >> style: aString [ - | stringToAdd | - aString isEmptyOrNil ifTrue: [ ^ self ]. - - stringToAdd := self - propertiesAt: #style: - ifPresent: [ :oldStyle | - String - streamContents: [ :aStream | - aStream - nextPutAll: oldStyle anyOne; - space; - nextPutAll: aString ] ] - ifAbsent: [ aString ]. - - self propertiesAt: #style: put: {stringToAdd} -] +" +I represent an abstract class for high level widgets. + +Interesting point is that I have properties through a Dictionary which allow me to add some behaviours. My properties should have a selector as key and an array of parameters as value. +" +Class { + #name : #MDLHighLevelWidget, + #superclass : #MDLWidget, + #instVars : [ + 'properties' + ], + #category : #'Material-Design-Lite-Widgets' +} + +{ #category : #accessing } +MDLHighLevelWidget >> addProperties: aDictionary [ + properties addAll: aDictionary +] + +{ #category : #actions } +MDLHighLevelWidget >> addPropertiesToBrush: aBrush [ + self properties keysAndValuesDo: [ :aSymbol :arguments | aBrush perform: aSymbol withArguments: arguments ] +] + +{ #category : #accessing } +MDLHighLevelWidget >> class: aString [ + | stringToAdd | + aString isEmptyOrNil ifTrue: [ ^ self ]. + + stringToAdd := self + propertiesAt: #class: + ifPresent: [ :oldClasses | + stringToAdd := String + streamContents: [ :aStream | + aStream + nextPutAll: oldClasses anyOne; + space; + nextPutAll: aString ] ] + ifAbsent: [ aString ]. + + self propertiesAt: #class: put: (Array with: stringToAdd) +] + +{ #category : #accessing } +MDLHighLevelWidget >> htmlClass [ + "htmlClass because it can cause problems to have a #class method in objects." + + ^ self propertiesAt: #class ifPresent: [ :array | array anyOne ] ifAbsent: [ nil ] +] + +{ #category : #accessing } +MDLHighLevelWidget >> id [ + ^ self propertiesAt: #id: ifPresent: [ :array | array anyOne ] ifAbsent: [ nil ] +] + +{ #category : #accessing } +MDLHighLevelWidget >> id: aString [ + self propertiesAt: #id: put: (Array with: aString) +] + +{ #category : #initialization } +MDLHighLevelWidget >> initialize [ + super initialize. + properties := OrderedDictionary new +] + +{ #category : #accessing } +MDLHighLevelWidget >> onClick: anObject [ + self propertiesAt: #onClick: put: (Array with: anObject) +] + +{ #category : #accessing } +MDLHighLevelWidget >> properties [ + ^ properties +] + +{ #category : #accessing } +MDLHighLevelWidget >> propertiesAt: aString [ + ^ self properties at: aString +] + +{ #category : #accessing } +MDLHighLevelWidget >> propertiesAt: aString ifAbsent: aBlock [ + ^ self properties at: aString ifAbsent: aBlock +] + +{ #category : #accessing } +MDLHighLevelWidget >> propertiesAt: aString ifPresent: aBlock ifAbsent: anotherBlock [ + ^ self properties at: aString ifPresent: aBlock ifAbsent: anotherBlock +] + +{ #category : #accessing } +MDLHighLevelWidget >> propertiesAt: aString put: anArray [ + self properties at: aString put: anArray +] + +{ #category : #accessing } +MDLHighLevelWidget >> style: aString [ + | stringToAdd | + aString isEmptyOrNil ifTrue: [ ^ self ]. + + stringToAdd := self + propertiesAt: #style: + ifPresent: [ :oldStyle | + String + streamContents: [ :aStream | + aStream + nextPutAll: oldStyle anyOne; + space; + nextPutAll: aString ] ] + ifAbsent: [ aString ]. + + self propertiesAt: #style: put: {stringToAdd} +] diff --git a/src/Material-Design-Lite-Widgets/MDLIconComponent.class.st b/src/Material-Design-Lite-Widgets/MDLIconComponent.class.st index 6757f8ff..a45ac400 100644 --- a/src/Material-Design-Lite-Widgets/MDLIconComponent.class.st +++ b/src/Material-Design-Lite-Widgets/MDLIconComponent.class.st @@ -1,29 +1,29 @@ -" -Description --------------------- - -I am a brush to create a -" -Class { - #name : #MDLIconComponent, - #superclass : #WAComponent, - #instVars : [ - 'iconName' - ], - #category : #'Material-Design-Lite-Widgets' -} - -{ #category : #accessing } -MDLIconComponent >> iconName [ - ^ iconName -] - -{ #category : #accessing } -MDLIconComponent >> iconName: anObject [ - iconName := anObject -] - -{ #category : #rendering } -MDLIconComponent >> renderContentOn: html [ - iconName ifNotNil: [ html mdlIcon: iconName ] ifNil: [ html text: 'No icon name set' ] -] +" +Description +-------------------- + +I am a brush to create a +" +Class { + #name : #MDLIconComponent, + #superclass : #WAComponent, + #instVars : [ + 'iconName' + ], + #category : #'Material-Design-Lite-Widgets' +} + +{ #category : #accessing } +MDLIconComponent >> iconName [ + ^ iconName +] + +{ #category : #accessing } +MDLIconComponent >> iconName: anObject [ + iconName := anObject +] + +{ #category : #rendering } +MDLIconComponent >> renderContentOn: html [ + iconName ifNotNil: [ html mdlIcon: iconName ] ifNil: [ html text: 'No icon name set' ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLIconDrawerSection.class.st b/src/Material-Design-Lite-Widgets/MDLIconDrawerSection.class.st index 44bccfcc..b0eee6be 100644 --- a/src/Material-Design-Lite-Widgets/MDLIconDrawerSection.class.st +++ b/src/Material-Design-Lite-Widgets/MDLIconDrawerSection.class.st @@ -1,26 +1,26 @@ -Class { - #name : #MDLIconDrawerSection, - #superclass : #MDLLinkingLayoutSection, - #category : 'Material-Design-Lite-Widgets-Header' -} - -{ #category : #accessing } -MDLIconDrawerSection >> links: someLinks [ - "here links must be seaside components" - ^ super links: someLinks -] - -{ #category : #'as yet unclassified' } -MDLIconDrawerSection >> renderContentOn: html [ - html - mdlLayoutDrawer: [ - html mdlLayoutTitle - style: 'border-bottom: 1px solid #e0e0e0; margin: 0px 0px 16px 0px'; - with: layout title. - self renderLinksOn: html ] -] - -{ #category : #'as yet unclassified' } -MDLIconDrawerSection >> renderLinksOn: html [ - links do: [ :aLink | html render: aLink ] -] +Class { + #name : #MDLIconDrawerSection, + #superclass : #MDLLinkingLayoutSection, + #category : 'Material-Design-Lite-Widgets-Header' +} + +{ #category : #accessing } +MDLIconDrawerSection >> links: someLinks [ + "here links must be seaside components" + ^ super links: someLinks +] + +{ #category : #'as yet unclassified' } +MDLIconDrawerSection >> renderContentOn: html [ + html + mdlLayoutDrawer: [ + html mdlLayoutTitle + style: 'border-bottom: 1px solid #e0e0e0; margin: 0px 0px 16px 0px'; + with: layout title. + self renderLinksOn: html ] +] + +{ #category : #'as yet unclassified' } +MDLIconDrawerSection >> renderLinksOn: html [ + links do: [ :aLink | html render: aLink ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLInsensitiveBeginsWithFilter.class.st b/src/Material-Design-Lite-Widgets/MDLInsensitiveBeginsWithFilter.class.st index 4f53a52b..4721f978 100644 --- a/src/Material-Design-Lite-Widgets/MDLInsensitiveBeginsWithFilter.class.st +++ b/src/Material-Design-Lite-Widgets/MDLInsensitiveBeginsWithFilter.class.st @@ -1,13 +1,13 @@ -" -I am a nested list filter keeping only elements whose name begins with the pattern passed by the user in an insensitive way. -" -Class { - #name : #MDLInsensitiveBeginsWithFilter, - #superclass : #MDLAbstractFilter, - #category : 'Material-Design-Lite-Widgets-List' -} - -{ #category : #accessing } -MDLInsensitiveBeginsWithFilter class >> formatedElement: aString matches: aPattern [ - ^ aString asLowercase beginsWith: aPattern asLowercase -] +" +I am a nested list filter keeping only elements whose name begins with the pattern passed by the user in an insensitive way. +" +Class { + #name : #MDLInsensitiveBeginsWithFilter, + #superclass : #MDLAbstractFilter, + #category : 'Material-Design-Lite-Widgets-List' +} + +{ #category : #accessing } +MDLInsensitiveBeginsWithFilter class >> formatedElement: aString matches: aPattern [ + ^ aString asLowercase beginsWith: aPattern asLowercase +] diff --git a/src/Material-Design-Lite-Widgets/MDLInsensitiveSubstringFilter.class.st b/src/Material-Design-Lite-Widgets/MDLInsensitiveSubstringFilter.class.st index e6a50dff..1f2ed870 100644 --- a/src/Material-Design-Lite-Widgets/MDLInsensitiveSubstringFilter.class.st +++ b/src/Material-Design-Lite-Widgets/MDLInsensitiveSubstringFilter.class.st @@ -1,13 +1,13 @@ -" -I am a nested list filter keeping only elements whose name includes the pattern passed by the user, non case sensitive. -" -Class { - #name : #MDLInsensitiveSubstringFilter, - #superclass : #MDLAbstractFilter, - #category : 'Material-Design-Lite-Widgets-List' -} - -{ #category : #accessing } -MDLInsensitiveSubstringFilter class >> formatedElement: aString matches: aPattern [ - ^ aString asLowercase includesSubstring: aPattern asLowercase -] +" +I am a nested list filter keeping only elements whose name includes the pattern passed by the user, non case sensitive. +" +Class { + #name : #MDLInsensitiveSubstringFilter, + #superclass : #MDLAbstractFilter, + #category : 'Material-Design-Lite-Widgets-List' +} + +{ #category : #accessing } +MDLInsensitiveSubstringFilter class >> formatedElement: aString matches: aPattern [ + ^ aString asLowercase includesSubstring: aPattern asLowercase +] diff --git a/src/Material-Design-Lite-Widgets/MDLLayoutWidget.class.st b/src/Material-Design-Lite-Widgets/MDLLayoutWidget.class.st index b8c58fac..923d5710 100644 --- a/src/Material-Design-Lite-Widgets/MDLLayoutWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLLayoutWidget.class.st @@ -1,110 +1,110 @@ -Class { - #name : #MDLLayoutWidget, - #superclass : #MDLWidget, - #instVars : [ - 'title', - 'icon', - 'headerSection', - 'drawerSection', - 'contentBlock', - 'brush' - ], - #category : 'Material-Design-Lite-Widgets-Header' -} - -{ #category : #accessing } -MDLLayoutWidget >> contentBlock [ - ^ contentBlock -] - -{ #category : #accessing } -MDLLayoutWidget >> contentBlock: anObject [ - contentBlock := anObject -] - -{ #category : #accessing } -MDLLayoutWidget >> drawerSection [ - ^ drawerSection -] - -{ #category : #accessing } -MDLLayoutWidget >> drawerSection: anObject [ - anObject layout: self. - drawerSection := anObject -] - -{ #category : #options } -MDLLayoutWidget >> fixedDrawer [ - ^ brush fixedDrawer -] - -{ #category : #options } -MDLLayoutWidget >> fixedHeader [ - ^ brush fixedHeader -] - -{ #category : #options } -MDLLayoutWidget >> fixedTabs [ - ^ brush fixedTabs -] - -{ #category : #accessing } -MDLLayoutWidget >> headerSection [ - ^ headerSection -] - -{ #category : #accessing } -MDLLayoutWidget >> headerSection: anObject [ - anObject layout: self. - headerSection := anObject -] - -{ #category : #accessing } -MDLLayoutWidget >> icon [ - ^ icon -] - -{ #category : #accessing } -MDLLayoutWidget >> icon: anObject [ - icon := anObject -] - -{ #category : #initialization } -MDLLayoutWidget >> initialize [ - super initialize. - title := 'Define a title'. - icon := MDLIconComponent new. - headerSection := MDLNilLayoutSection new. - drawerSection := MDLNilLayoutSection new. - contentBlock := [ ]. - brush := MDLLayout new. -] - -{ #category : #options } -MDLLayoutWidget >> noDesktopDrawerButton [ - ^ brush noDesktopDrawerButton -] - -{ #category : #options } -MDLLayoutWidget >> noDrawerButton [ - ^ brush noDrawerButton -] - -{ #category : #rendering } -MDLLayoutWidget >> renderContentOn: html [ - (html brush: brush) - with: [ - html render: headerSection. - html render: drawerSection. - html mdlLayoutContent: contentBlock ]. -] - -{ #category : #accessing } -MDLLayoutWidget >> title [ - ^ title -] - -{ #category : #accessing } -MDLLayoutWidget >> title: anObject [ - title := anObject -] +Class { + #name : #MDLLayoutWidget, + #superclass : #MDLWidget, + #instVars : [ + 'title', + 'icon', + 'headerSection', + 'drawerSection', + 'contentBlock', + 'brush' + ], + #category : 'Material-Design-Lite-Widgets-Header' +} + +{ #category : #accessing } +MDLLayoutWidget >> contentBlock [ + ^ contentBlock +] + +{ #category : #accessing } +MDLLayoutWidget >> contentBlock: anObject [ + contentBlock := anObject +] + +{ #category : #accessing } +MDLLayoutWidget >> drawerSection [ + ^ drawerSection +] + +{ #category : #accessing } +MDLLayoutWidget >> drawerSection: anObject [ + anObject layout: self. + drawerSection := anObject +] + +{ #category : #options } +MDLLayoutWidget >> fixedDrawer [ + ^ brush fixedDrawer +] + +{ #category : #options } +MDLLayoutWidget >> fixedHeader [ + ^ brush fixedHeader +] + +{ #category : #options } +MDLLayoutWidget >> fixedTabs [ + ^ brush fixedTabs +] + +{ #category : #accessing } +MDLLayoutWidget >> headerSection [ + ^ headerSection +] + +{ #category : #accessing } +MDLLayoutWidget >> headerSection: anObject [ + anObject layout: self. + headerSection := anObject +] + +{ #category : #accessing } +MDLLayoutWidget >> icon [ + ^ icon +] + +{ #category : #accessing } +MDLLayoutWidget >> icon: anObject [ + icon := anObject +] + +{ #category : #initialization } +MDLLayoutWidget >> initialize [ + super initialize. + title := 'Define a title'. + icon := MDLIconComponent new. + headerSection := MDLNilLayoutSection new. + drawerSection := MDLNilLayoutSection new. + contentBlock := [ ]. + brush := MDLLayout new. +] + +{ #category : #options } +MDLLayoutWidget >> noDesktopDrawerButton [ + ^ brush noDesktopDrawerButton +] + +{ #category : #options } +MDLLayoutWidget >> noDrawerButton [ + ^ brush noDrawerButton +] + +{ #category : #rendering } +MDLLayoutWidget >> renderContentOn: html [ + (html brush: brush) + with: [ + html render: headerSection. + html render: drawerSection. + html mdlLayoutContent: contentBlock ]. +] + +{ #category : #accessing } +MDLLayoutWidget >> title [ + ^ title +] + +{ #category : #accessing } +MDLLayoutWidget >> title: anObject [ + title := anObject +] diff --git a/src/Material-Design-Lite-Widgets/MDLLazyExpansionStrategy.class.st b/src/Material-Design-Lite-Widgets/MDLLazyExpansionStrategy.class.st index 56432b87..514d3c7a 100644 --- a/src/Material-Design-Lite-Widgets/MDLLazyExpansionStrategy.class.st +++ b/src/Material-Design-Lite-Widgets/MDLLazyExpansionStrategy.class.st @@ -1,42 +1,42 @@ -" -I am a lazy expansion strategy. -I combine the best from MDLHideExpansionStrategy and MDLAjaxExpansionStrategy to load the panel content only once when it is needed. - -That is to say, if the panel is initially rendered folded, the first time the user click the expansion panel to expand it, I will perform an AJAX call to ask the server to render the content. -Then, next times the user click on the expansion panel, I will behave as MDLHideExpansionStrategy. - -If the panel is initially rendered expanded, I behave exactly as MDLHideExpansionStrategy. -" -Class { - #name : #MDLLazyExpansionStrategy, - #superclass : #MDLExpansionStrategy, - #instVars : [ - 'currentStrategy' - ], - #category : #'Material-Design-Lite-Widgets-Expansion' -} - -{ #category : #javascript } -MDLLazyExpansionStrategy >> customize: anExpansionPanelHeader in: anExpansionPanel on: html [ - anExpansionPanel isExpanded ifTrue: [ self switchToDisplayNoneStrategy ]. - - ^ currentStrategy customize: anExpansionPanelHeader in: anExpansionPanel on: html -] - -{ #category : #initialization } -MDLLazyExpansionStrategy >> initialize [ - super initialize. - currentStrategy := MDLAjaxExpansionStrategy new -] - -{ #category : #rendering } -MDLLazyExpansionStrategy >> renderExpansionPanel: anExpansionPanel contentOn: html [ - anExpansionPanel isExpanded ifTrue: [ self switchToDisplayNoneStrategy ]. - currentStrategy renderExpansionPanel: anExpansionPanel contentOn: html. - currentStrategy isAjaxExpansionStrategy ifTrue: [ self switchToDisplayNoneStrategy ] -] - -{ #category : #private } -MDLLazyExpansionStrategy >> switchToDisplayNoneStrategy [ - currentStrategy := MDLHideExpansionStrategy new -] +" +I am a lazy expansion strategy. +I combine the best from MDLHideExpansionStrategy and MDLAjaxExpansionStrategy to load the panel content only once when it is needed. + +That is to say, if the panel is initially rendered folded, the first time the user click the expansion panel to expand it, I will perform an AJAX call to ask the server to render the content. +Then, next times the user click on the expansion panel, I will behave as MDLHideExpansionStrategy. + +If the panel is initially rendered expanded, I behave exactly as MDLHideExpansionStrategy. +" +Class { + #name : #MDLLazyExpansionStrategy, + #superclass : #MDLExpansionStrategy, + #instVars : [ + 'currentStrategy' + ], + #category : #'Material-Design-Lite-Widgets-Expansion' +} + +{ #category : #javascript } +MDLLazyExpansionStrategy >> customize: anExpansionPanelHeader in: anExpansionPanel on: html [ + anExpansionPanel isExpanded ifTrue: [ self switchToDisplayNoneStrategy ]. + + ^ currentStrategy customize: anExpansionPanelHeader in: anExpansionPanel on: html +] + +{ #category : #initialization } +MDLLazyExpansionStrategy >> initialize [ + super initialize. + currentStrategy := MDLAjaxExpansionStrategy new +] + +{ #category : #rendering } +MDLLazyExpansionStrategy >> renderExpansionPanel: anExpansionPanel contentOn: html [ + anExpansionPanel isExpanded ifTrue: [ self switchToDisplayNoneStrategy ]. + currentStrategy renderExpansionPanel: anExpansionPanel contentOn: html. + currentStrategy isAjaxExpansionStrategy ifTrue: [ self switchToDisplayNoneStrategy ] +] + +{ #category : #private } +MDLLazyExpansionStrategy >> switchToDisplayNoneStrategy [ + currentStrategy := MDLHideExpansionStrategy new +] diff --git a/src/Material-Design-Lite-Widgets/MDLLinkingLayoutSection.class.st b/src/Material-Design-Lite-Widgets/MDLLinkingLayoutSection.class.st index 99b9aa2f..d7f772f0 100644 --- a/src/Material-Design-Lite-Widgets/MDLLinkingLayoutSection.class.st +++ b/src/Material-Design-Lite-Widgets/MDLLinkingLayoutSection.class.st @@ -1,39 +1,39 @@ -Class { - #name : #MDLLinkingLayoutSection, - #superclass : #MDLAbstractLayoutSection, - #instVars : [ - 'links' - ], - #category : 'Material-Design-Lite-Widgets-Header' -} - -{ #category : #initialization } -MDLLinkingLayoutSection >> initialize [ - super initialize. - links := OrderedCollection new. -] - -{ #category : #accessing } -MDLLinkingLayoutSection >> links [ - ^ links -] - -{ #category : #accessing } -MDLLinkingLayoutSection >> links: anOrderedCollection [ - "This should be a collection of dictionaries Text -> callback" - links := anOrderedCollection -] - -{ #category : #rendering } -MDLLinkingLayoutSection >> renderLinksOn: html [ - self links - do: [ :aDictionary | - html - mdlNavigation: [ - aDictionary - keysAndValuesDo: [ :label :callback | - html mdlNavigationLink - callback: callback; - with: label ] ]. - html mdlLayoutSpacer ] -] +Class { + #name : #MDLLinkingLayoutSection, + #superclass : #MDLAbstractLayoutSection, + #instVars : [ + 'links' + ], + #category : 'Material-Design-Lite-Widgets-Header' +} + +{ #category : #initialization } +MDLLinkingLayoutSection >> initialize [ + super initialize. + links := OrderedCollection new. +] + +{ #category : #accessing } +MDLLinkingLayoutSection >> links [ + ^ links +] + +{ #category : #accessing } +MDLLinkingLayoutSection >> links: anOrderedCollection [ + "This should be a collection of dictionaries Text -> callback" + links := anOrderedCollection +] + +{ #category : #rendering } +MDLLinkingLayoutSection >> renderLinksOn: html [ + self links + do: [ :aDictionary | + html + mdlNavigation: [ + aDictionary + keysAndValuesDo: [ :label :callback | + html mdlNavigationLink + callback: callback; + with: label ] ]. + html mdlLayoutSpacer ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLListIconComponent.class.st b/src/Material-Design-Lite-Widgets/MDLListIconComponent.class.st index b90fd2b6..35d0f608 100644 --- a/src/Material-Design-Lite-Widgets/MDLListIconComponent.class.st +++ b/src/Material-Design-Lite-Widgets/MDLListIconComponent.class.st @@ -1,57 +1,57 @@ -" -I am a simple component to display a MDL icon with an help text. My main purpose is to serve in a MDLNestedList to display a MDL icon. -" -Class { - #name : #MDLListIconComponent, - #superclass : #WAComponent, - #instVars : [ - 'label', - 'helpText' - ], - #category : 'Material-Design-Lite-Widgets-List' -} - -{ #category : #'instance creation' } -MDLListIconComponent class >> named: aString helpText: aTranslatedString [ - ^ self new - label: aString; - helpText: aTranslatedString; - yourself -] - -{ #category : #accessing } -MDLListIconComponent >> helpText [ - ^ helpText -] - -{ #category : #accessing } -MDLListIconComponent >> helpText: anObject [ - helpText := anObject -] - -{ #category : #accessing } -MDLListIconComponent >> label [ - ^ label -] - -{ #category : #accessing } -MDLListIconComponent >> label: anObject [ - label := anObject -] - -{ #category : #rendering } -MDLListIconComponent >> renderContentOn: html [ - | id | - id := html nextId. - html mdlIcon - id: id; - with: self label. - - (self helpText isNil or: [ self helpText isEmpty ]) - ifTrue: [ ^ self ]. - - html mdlTooltip - large; - for: id; - with: [ html text: self helpText ] -] +" +I am a simple component to display a MDL icon with an help text. My main purpose is to serve in a MDLNestedList to display a MDL icon. +" +Class { + #name : #MDLListIconComponent, + #superclass : #WAComponent, + #instVars : [ + 'label', + 'helpText' + ], + #category : 'Material-Design-Lite-Widgets-List' +} + +{ #category : #'instance creation' } +MDLListIconComponent class >> named: aString helpText: aTranslatedString [ + ^ self new + label: aString; + helpText: aTranslatedString; + yourself +] + +{ #category : #accessing } +MDLListIconComponent >> helpText [ + ^ helpText +] + +{ #category : #accessing } +MDLListIconComponent >> helpText: anObject [ + helpText := anObject +] + +{ #category : #accessing } +MDLListIconComponent >> label [ + ^ label +] + +{ #category : #accessing } +MDLListIconComponent >> label: anObject [ + label := anObject +] + +{ #category : #rendering } +MDLListIconComponent >> renderContentOn: html [ + | id | + id := html nextId. + html mdlIcon + id: id; + with: self label. + + (self helpText isNil or: [ self helpText isEmpty ]) + ifTrue: [ ^ self ]. + + html mdlTooltip + large; + for: id; + with: [ html text: self helpText ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLLoginCardWidget.class.st b/src/Material-Design-Lite-Widgets/MDLLoginCardWidget.class.st index a220290f..3298b80a 100644 --- a/src/Material-Design-Lite-Widgets/MDLLoginCardWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLLoginCardWidget.class.st @@ -1,21 +1,21 @@ -" -I'm a login widget render in a card widget -" -Class { - #name : #MDLLoginCardWidget, - #superclass : #MDLLoginWidget, - #category : 'Material-Design-Lite-Widgets' -} - -{ #category : #rendering } -MDLLoginCardWidget >> renderContentOn: html [ - html - render: - (MDLCardWidget new - shadow: 2; - class: 'mdl-card__login-widget'; - class: self htmlClass; - title: titleLabel level: titleLevel; - addTextContainer: [ :canvas | super renderContentOn: canvas ]; - yourself) -] +" +I'm a login widget render in a card widget +" +Class { + #name : #MDLLoginCardWidget, + #superclass : #MDLLoginWidget, + #category : 'Material-Design-Lite-Widgets' +} + +{ #category : #rendering } +MDLLoginCardWidget >> renderContentOn: html [ + html + render: + (MDLCardWidget new + shadow: 2; + class: 'mdl-card__login-widget'; + class: self htmlClass; + title: titleLabel level: titleLevel; + addTextContainer: [ :canvas | super renderContentOn: canvas ]; + yourself) +] diff --git a/src/Material-Design-Lite-Widgets/MDLLoginDialogWidget.class.st b/src/Material-Design-Lite-Widgets/MDLLoginDialogWidget.class.st index 0fb282aa..480bcbe1 100644 --- a/src/Material-Design-Lite-Widgets/MDLLoginDialogWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLLoginDialogWidget.class.st @@ -1,76 +1,76 @@ -" -I represent the login widget but I am display in a dialog -" -Class { - #name : #MDLLoginDialogWidget, - #superclass : #MDLLoginWidget, - #instVars : [ - 'closeId', - 'openId', - 'signInTitleLabel', - 'signInButtonLabel' - ], - #category : 'Material-Design-Lite-Widgets' -} - -{ #category : #accessing } -MDLLoginDialogWidget >> closeId [ - ^ closeId -] - -{ #category : #accessing } -MDLLoginDialogWidget >> closeId: anObject [ - ^ closeId := anObject -] - -{ #category : #initialization } -MDLLoginDialogWidget >> initialize [ - super initialize. - signInTitleLabel := 'Sign In'. - signInButtonLabel := 'Sign In' -] - -{ #category : #accessing } -MDLLoginDialogWidget >> openId [ - ^ openId -] - -{ #category : #accessing } -MDLLoginDialogWidget >> openId: anObject [ - ^ openId := anObject -] - -{ #category : #rendering } -MDLLoginDialogWidget >> renderCancelButtonOn: html [ - html mdlButton - id: closeId; - raised; - with: cancelLabel -] - -{ #category : #rendering } -MDLLoginDialogWidget >> renderContentOn: html [ - self renderOpenButtonOn: html. - self renderLoginDialogOn: html -] - -{ #category : #rendering } -MDLLoginDialogWidget >> renderLoginDialogOn: html [ - html mdlDialog - openButtonId: openId; - closeButtonId: (closeId := html nextId); - with: [ html mdlDialogTitle - class: 'mdl-color--primary'; - with: signInTitleLabel. - html mdlDialogContent: [ super renderContentOn: html ] ] -] - -{ #category : #rendering } -MDLLoginDialogWidget >> renderOpenButtonOn: html [ - html mdlButton - id: (openId := html nextId); - raised; - colored; - rippleEffect; - with: signInButtonLabel -] +" +I represent the login widget but I am display in a dialog +" +Class { + #name : #MDLLoginDialogWidget, + #superclass : #MDLLoginWidget, + #instVars : [ + 'closeId', + 'openId', + 'signInTitleLabel', + 'signInButtonLabel' + ], + #category : 'Material-Design-Lite-Widgets' +} + +{ #category : #accessing } +MDLLoginDialogWidget >> closeId [ + ^ closeId +] + +{ #category : #accessing } +MDLLoginDialogWidget >> closeId: anObject [ + ^ closeId := anObject +] + +{ #category : #initialization } +MDLLoginDialogWidget >> initialize [ + super initialize. + signInTitleLabel := 'Sign In'. + signInButtonLabel := 'Sign In' +] + +{ #category : #accessing } +MDLLoginDialogWidget >> openId [ + ^ openId +] + +{ #category : #accessing } +MDLLoginDialogWidget >> openId: anObject [ + ^ openId := anObject +] + +{ #category : #rendering } +MDLLoginDialogWidget >> renderCancelButtonOn: html [ + html mdlButton + id: closeId; + raised; + with: cancelLabel +] + +{ #category : #rendering } +MDLLoginDialogWidget >> renderContentOn: html [ + self renderOpenButtonOn: html. + self renderLoginDialogOn: html +] + +{ #category : #rendering } +MDLLoginDialogWidget >> renderLoginDialogOn: html [ + html mdlDialog + openButtonId: openId; + closeButtonId: (closeId := html nextId); + with: [ html mdlDialogTitle + class: 'mdl-color--primary'; + with: signInTitleLabel. + html mdlDialogContent: [ super renderContentOn: html ] ] +] + +{ #category : #rendering } +MDLLoginDialogWidget >> renderOpenButtonOn: html [ + html mdlButton + id: (openId := html nextId); + raised; + colored; + rippleEffect; + with: signInButtonLabel +] diff --git a/src/Material-Design-Lite-Widgets/MDLLoginWidget.class.st b/src/Material-Design-Lite-Widgets/MDLLoginWidget.class.st index d461f204..d39fe943 100644 --- a/src/Material-Design-Lite-Widgets/MDLLoginWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLLoginWidget.class.st @@ -1,147 +1,147 @@ -" -A login widget which use a MDLCardWidget - -I'm ready to use, you just have to give me a callback with 2 arguments (login and password) and insert me in a form. -" -Class { - #name : #MDLLoginWidget, - #superclass : #MDLHighLevelWidget, - #instVars : [ - 'titleLabel', - 'titleLevel', - 'loginLabel', - 'passwordLabel', - 'login', - 'password', - 'submitLabel', - 'callback', - 'cancelLabel', - 'cancelCallback' - ], - #category : #'Material-Design-Lite-Widgets' -} - -{ #category : #accessing } -MDLLoginWidget >> callback: anObject [ - callback := anObject -] - -{ #category : #accessing } -MDLLoginWidget >> cancelCallback [ - ^ cancelCallback ifNil: [ cancelCallback := [ ] ] -] - -{ #category : #accessing } -MDLLoginWidget >> cancelCallback: anObject [ - cancelCallback := anObject -] - -{ #category : #accessing } -MDLLoginWidget >> cancelLabel: anObject [ - cancelLabel := anObject -] - -{ #category : #initialization } -MDLLoginWidget >> initialize [ - super initialize. - titleLabel := 'Please, sign in'. - titleLevel := 2. - loginLabel := 'Login'. - cancelLabel := 'Cancel'. - passwordLabel := 'Password'. - submitLabel := 'Sign In' -] - -{ #category : #accessing } -MDLLoginWidget >> login [ - ^ login -] - -{ #category : #accessing } -MDLLoginWidget >> login: anObject [ - login := anObject -] - -{ #category : #rendering } -MDLLoginWidget >> loginInputWidget [ - ^ MDLTextFieldWidget new - beFloatingLabel; - on: #login of: self; - label: loginLabel; - yourself -] - -{ #category : #accessing } -MDLLoginWidget >> loginLabel: anObject [ - loginLabel := anObject -] - -{ #category : #accessing } -MDLLoginWidget >> password [ - ^ password -] - -{ #category : #accessing } -MDLLoginWidget >> password: anObject [ - password := anObject -] - -{ #category : #rendering } -MDLLoginWidget >> passwordInputWidget [ - ^ MDLTextFieldWidget new beFloatingLabel - type: 'password'; - on: #password of: self; - label: passwordLabel; - yourself -] - -{ #category : #accessing } -MDLLoginWidget >> passwordLabel: anObject [ - passwordLabel := anObject -] - -{ #category : #rendering } -MDLLoginWidget >> renderCancelButtonOn: html [ - html anchor - class: 'mdl-button mdl-js-button mdl-button--raised'; - callback: self cancelCallback; - with: cancelLabel -] - -{ #category : #rendering } -MDLLoginWidget >> renderContentOn: html [ - self renderFieldsOn: html. - self renderSubmitButtonOn: html. - self renderCancelButtonOn: html -] - -{ #category : #rendering } -MDLLoginWidget >> renderFieldsOn: html [ - html render: self loginInputWidget. - html render: self passwordInputWidget -] - -{ #category : #rendering } -MDLLoginWidget >> renderSubmitButtonOn: html [ - html mdlButton - raised; - accentColor; - beSubmit; - callback: [ callback value: login value: password ]; - with: submitLabel -] - -{ #category : #accessing } -MDLLoginWidget >> submitLabel: anObject [ - submitLabel := anObject -] - -{ #category : #accessing } -MDLLoginWidget >> titleLabel: anObject [ - titleLabel := anObject -] - -{ #category : #accessing } -MDLLoginWidget >> titleLevel: anObject [ - titleLevel := anObject -] +" +A login widget which use a MDLCardWidget + +I'm ready to use, you just have to give me a callback with 2 arguments (login and password) and insert me in a form. +" +Class { + #name : #MDLLoginWidget, + #superclass : #MDLHighLevelWidget, + #instVars : [ + 'titleLabel', + 'titleLevel', + 'loginLabel', + 'passwordLabel', + 'login', + 'password', + 'submitLabel', + 'callback', + 'cancelLabel', + 'cancelCallback' + ], + #category : #'Material-Design-Lite-Widgets' +} + +{ #category : #accessing } +MDLLoginWidget >> callback: anObject [ + callback := anObject +] + +{ #category : #accessing } +MDLLoginWidget >> cancelCallback [ + ^ cancelCallback ifNil: [ cancelCallback := [ ] ] +] + +{ #category : #accessing } +MDLLoginWidget >> cancelCallback: anObject [ + cancelCallback := anObject +] + +{ #category : #accessing } +MDLLoginWidget >> cancelLabel: anObject [ + cancelLabel := anObject +] + +{ #category : #initialization } +MDLLoginWidget >> initialize [ + super initialize. + titleLabel := 'Please, sign in'. + titleLevel := 2. + loginLabel := 'Login'. + cancelLabel := 'Cancel'. + passwordLabel := 'Password'. + submitLabel := 'Sign In' +] + +{ #category : #accessing } +MDLLoginWidget >> login [ + ^ login +] + +{ #category : #accessing } +MDLLoginWidget >> login: anObject [ + login := anObject +] + +{ #category : #rendering } +MDLLoginWidget >> loginInputWidget [ + ^ MDLTextFieldWidget new + beFloatingLabel; + on: #login of: self; + label: loginLabel; + yourself +] + +{ #category : #accessing } +MDLLoginWidget >> loginLabel: anObject [ + loginLabel := anObject +] + +{ #category : #accessing } +MDLLoginWidget >> password [ + ^ password +] + +{ #category : #accessing } +MDLLoginWidget >> password: anObject [ + password := anObject +] + +{ #category : #rendering } +MDLLoginWidget >> passwordInputWidget [ + ^ MDLTextFieldWidget new beFloatingLabel + type: 'password'; + on: #password of: self; + label: passwordLabel; + yourself +] + +{ #category : #accessing } +MDLLoginWidget >> passwordLabel: anObject [ + passwordLabel := anObject +] + +{ #category : #rendering } +MDLLoginWidget >> renderCancelButtonOn: html [ + html anchor + class: 'mdl-button mdl-js-button mdl-button--raised'; + callback: self cancelCallback; + with: cancelLabel +] + +{ #category : #rendering } +MDLLoginWidget >> renderContentOn: html [ + self renderFieldsOn: html. + self renderSubmitButtonOn: html. + self renderCancelButtonOn: html +] + +{ #category : #rendering } +MDLLoginWidget >> renderFieldsOn: html [ + html render: self loginInputWidget. + html render: self passwordInputWidget +] + +{ #category : #rendering } +MDLLoginWidget >> renderSubmitButtonOn: html [ + html mdlButton + raised; + accentColor; + beSubmit; + callback: [ callback value: login value: password ]; + with: submitLabel +] + +{ #category : #accessing } +MDLLoginWidget >> submitLabel: anObject [ + submitLabel := anObject +] + +{ #category : #accessing } +MDLLoginWidget >> titleLabel: anObject [ + titleLabel := anObject +] + +{ #category : #accessing } +MDLLoginWidget >> titleLevel: anObject [ + titleLevel := anObject +] diff --git a/src/Material-Design-Lite-Widgets/MDLMegaFooterLinksList.class.st b/src/Material-Design-Lite-Widgets/MDLMegaFooterLinksList.class.st index 8289efa0..5fee0a2c 100644 --- a/src/Material-Design-Lite-Widgets/MDLMegaFooterLinksList.class.st +++ b/src/Material-Design-Lite-Widgets/MDLMegaFooterLinksList.class.st @@ -1,11 +1,11 @@ -Class { - #name : #MDLMegaFooterLinksList, - #superclass : #MDLAbstractFooterLinksList, - #category : 'Material-Design-Lite-Widgets-Footer' -} - -{ #category : #'as yet unclassified' } -MDLMegaFooterLinksList >> renderLinksListOn: html [ - html mdlFooterLinkList: [ - self renderLinksOn: html ] -] +Class { + #name : #MDLMegaFooterLinksList, + #superclass : #MDLAbstractFooterLinksList, + #category : 'Material-Design-Lite-Widgets-Footer' +} + +{ #category : #'as yet unclassified' } +MDLMegaFooterLinksList >> renderLinksListOn: html [ + html mdlFooterLinkList: [ + self renderLinksOn: html ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLMenuButtonWidget.class.st b/src/Material-Design-Lite-Widgets/MDLMenuButtonWidget.class.st index 02f446b5..85a4b81c 100644 --- a/src/Material-Design-Lite-Widgets/MDLMenuButtonWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLMenuButtonWidget.class.st @@ -1,276 +1,276 @@ -" -Description --------------------- - -I am a mdl button that expand a menu to choose an item. When an item is selected I will refresh the page. - -Examples --------------------- - - (MDLMenuButtonWidget - possibilities: #('Guillaume' 'Kévin' 'Anne' 'Cyril' 'Olivier' 'Yann') - label: #asString - action: [ :o | Transcript crShow: o ] - choosingText: 'Select an user' - description: 'Choose a user to log into the Transcript') - sortBlock: [ :a :b | a < b ]; - yourself - -Internal Representation and Key Implementation Points. --------------------- - - Instance Variables - action: Callback taking the selected element as parameter - buttonContent: The content of the button. Can be a string or a block. The block takes an html canvas as parameter - description: Tooltip to show on the button - objectsPossibilities: Collection of object to select from - selectedObject: Selected object by default - sortBlock: A block to sort the elements of the menu - textBlock: A block taking a possible object as parameter and returning a string to display on the menu - -" -Class { - #name : #MDLMenuButtonWidget, - #superclass : #MDLWidget, - #instVars : [ - 'textBlock', - 'selectedObject', - 'objectsPossibilities', - 'description', - 'action', - 'sortBlock', - 'buttonContent', - 'descriptionPosition' - ], - #category : #'Material-Design-Lite-Widgets-Menu' -} - -{ #category : #'instance creation' } -MDLMenuButtonWidget class >> possibilities: aCollectionOfObjects label: aLabelBlock action: anAction choosingText: aText [ - ^ self possibilities: aCollectionOfObjects label: aLabelBlock action: anAction choosingText: aText description: nil -] - -{ #category : #'instance creation' } -MDLMenuButtonWidget class >> possibilities: aCollectionOfObjects label: aLabelBlock action: anAction choosingText: aText description: aDescriptionValuable [ - ^ self - possibilities: aCollectionOfObjects - label: aLabelBlock - action: anAction - selectedObject: nil - choosingText: aText - description: aDescriptionValuable -] - -{ #category : #'instance creation' } -MDLMenuButtonWidget class >> possibilities: aCollectionOfObjects label: aLabelBlock action: anAction selectedObject: anObjectOrNil choosingText: aText [ - ^ self - possibilities: aCollectionOfObjects - label: aLabelBlock - action: anAction - selectedObject: anObjectOrNil - choosingText: aText - description: nil -] - -{ #category : #'instance creation' } -MDLMenuButtonWidget class >> possibilities: aCollectionOfObjects label: aLabelBlock action: anAction selectedObject: anObjectOrNil choosingText: aText description: aDescriptionValuable [ - ^ self new - choosingText: aText; - textBlock: aLabelBlock; - selectedObject: anObjectOrNil; - description: aDescriptionValuable; - action: anAction; - objectsPossibilities: aCollectionOfObjects; - yourself -] - -{ #category : #accessing } -MDLMenuButtonWidget >> action [ - ^ action -] - -{ #category : #accessing } -MDLMenuButtonWidget >> action: anObject [ - action := anObject -] - -{ #category : #private } -MDLMenuButtonWidget >> actionWith: anObject [ - self action ifNotNil: [ :block | block value: anObject] -] - -{ #category : #accessing } -MDLMenuButtonWidget >> buttonContent [ - ^ buttonContent ifNil: [ buttonContent := 'choose' ] -] - -{ #category : #accessing } -MDLMenuButtonWidget >> buttonContent: aBlockOrString [ - buttonContent := aBlockOrString -] - -{ #category : #accessing } -MDLMenuButtonWidget >> choosingText [ - "This method is to keep backward compatibility with old API. This might be suppress with the next major release." - - self buttonContent isString ifTrue: [ ^ self buttonContent ]. - - self error: 'This button was not configured to render a string but was configured with a block' -] - -{ #category : #accessing } -MDLMenuButtonWidget >> choosingText: aString [ - "This method is to keep backward compatibility with old API. This might be suppress with the next major release." - - self buttonContent: aString -] - -{ #category : #accessing } -MDLMenuButtonWidget >> description [ - ^ description -] - -{ #category : #accessing } -MDLMenuButtonWidget >> description: anObject [ - description := anObject -] - -{ #category : #options } -MDLMenuButtonWidget >> descriptionAtBottom [ - "Sets the description of the menu at its bottom." - self descriptionPosition: #bottom -] - -{ #category : #options } -MDLMenuButtonWidget >> descriptionAtLeft [ - "Sets the description of the menu at its left." - self descriptionPosition: #left -] - -{ #category : #options } -MDLMenuButtonWidget >> descriptionAtRight [ - "Sets the description of the menu at its right." - self descriptionPosition: #right -] - -{ #category : #options } -MDLMenuButtonWidget >> descriptionAtTop [ - "Sets the description of the menu at its top." - self descriptionPosition: #top -] - -{ #category : #accessing } -MDLMenuButtonWidget >> descriptionPosition [ - ^ descriptionPosition ifNil: [ descriptionPosition := #bottom ] -] - -{ #category : #accessing } -MDLMenuButtonWidget >> descriptionPosition: anObject [ - descriptionPosition := anObject -] - -{ #category : #private } -MDLMenuButtonWidget >> labelFor: anObject [ - ^ self textBlock ifNil: [ anObject asString ] ifNotNil: [ :tb | tb cull: anObject ] -] - -{ #category : #accessing } -MDLMenuButtonWidget >> objectsPossibilities [ - ^ objectsPossibilities -] - -{ #category : #accessing } -MDLMenuButtonWidget >> objectsPossibilities: anObject [ - objectsPossibilities := anObject -] - -{ #category : #accessing } -MDLMenuButtonWidget >> objectsPossibilitiesWithLabel [ - ^ (self objectsPossibilities collect: [ :anObject | (self labelFor: anObject) -> anObject ]) sorted: self sortBlock -] - -{ #category : #rendering } -MDLMenuButtonWidget >> renderButtonContentOn: html [ - self buttonContent isString - ifTrue: [ html render: self buttonContent ] - ifFalse: [ self buttonContent cull: html ] -] - -{ #category : #rendering } -MDLMenuButtonWidget >> renderButtonOn: html [ - html div - id: self id; - class: 'menuButtonWidgetButton mdl-button mdl-js-button menuButtonWidgetButton'; - disabled: self objectsPossibilities isEmpty; - with: [ self selectedObject - ifNil: [ self renderButtonContentOn: html ] - ifNotNil: [ :anObject | html text: (self labelFor: anObject) ]. - html mdlIcon: 'arrow_drop_down' ] -] - -{ #category : #rendering } -MDLMenuButtonWidget >> renderContentOn: html [ - self ensureId: html. - self renderButtonOn: html. - self renderMenuOn: html. - self renderTooltipOn: html. -] - -{ #category : #rendering } -MDLMenuButtonWidget >> renderMenuItemOn: html withAssociation: anAssociation [ - html - mdlMenuItem: [ - html anchor - callback: [ self actionWith: anAssociation value ]; - with: [ html text: anAssociation key ] ] -] - -{ #category : #rendering } -MDLMenuButtonWidget >> renderMenuOn: html [ - html mdlMenu - bottomLeft; - for: self id; - class: 'menuButtonWidgetMenu'; - with: [ self objectsPossibilitiesWithLabel do: [ :anAssociation | self renderMenuItemOn: html withAssociation: anAssociation ] ] -] - -{ #category : #rendering } -MDLMenuButtonWidget >> renderTooltipOn: html [ - self description ifNil: [ ^ self ]. - - html mdlTooltip - for: self id; - large; - position: self descriptionPosition; - with: self description -] - -{ #category : #accessing } -MDLMenuButtonWidget >> selectedObject [ - ^ selectedObject value -] - -{ #category : #accessing } -MDLMenuButtonWidget >> selectedObject: anObject [ - selectedObject := anObject -] - -{ #category : #accessing } -MDLMenuButtonWidget >> sortBlock [ - ^ sortBlock ifNil: [ sortBlock := [ :a :b | a <= b ] ] -] - -{ #category : #accessing } -MDLMenuButtonWidget >> sortBlock: anObject [ - sortBlock := anObject -] - -{ #category : #accessing } -MDLMenuButtonWidget >> textBlock [ - ^ textBlock -] - -{ #category : #accessing } -MDLMenuButtonWidget >> textBlock: anObject [ - textBlock := anObject -] +" +Description +-------------------- + +I am a mdl button that expand a menu to choose an item. When an item is selected I will refresh the page. + +Examples +-------------------- + + (MDLMenuButtonWidget + possibilities: #('Guillaume' 'Kévin' 'Anne' 'Cyril' 'Olivier' 'Yann') + label: #asString + action: [ :o | Transcript crShow: o ] + choosingText: 'Select an user' + description: 'Choose a user to log into the Transcript') + sortBlock: [ :a :b | a < b ]; + yourself + +Internal Representation and Key Implementation Points. +-------------------- + + Instance Variables + action: Callback taking the selected element as parameter + buttonContent: The content of the button. Can be a string or a block. The block takes an html canvas as parameter + description: Tooltip to show on the button + objectsPossibilities: Collection of object to select from + selectedObject: Selected object by default + sortBlock: A block to sort the elements of the menu + textBlock: A block taking a possible object as parameter and returning a string to display on the menu + +" +Class { + #name : #MDLMenuButtonWidget, + #superclass : #MDLWidget, + #instVars : [ + 'textBlock', + 'selectedObject', + 'objectsPossibilities', + 'description', + 'action', + 'sortBlock', + 'buttonContent', + 'descriptionPosition' + ], + #category : #'Material-Design-Lite-Widgets-Menu' +} + +{ #category : #'instance creation' } +MDLMenuButtonWidget class >> possibilities: aCollectionOfObjects label: aLabelBlock action: anAction choosingText: aText [ + ^ self possibilities: aCollectionOfObjects label: aLabelBlock action: anAction choosingText: aText description: nil +] + +{ #category : #'instance creation' } +MDLMenuButtonWidget class >> possibilities: aCollectionOfObjects label: aLabelBlock action: anAction choosingText: aText description: aDescriptionValuable [ + ^ self + possibilities: aCollectionOfObjects + label: aLabelBlock + action: anAction + selectedObject: nil + choosingText: aText + description: aDescriptionValuable +] + +{ #category : #'instance creation' } +MDLMenuButtonWidget class >> possibilities: aCollectionOfObjects label: aLabelBlock action: anAction selectedObject: anObjectOrNil choosingText: aText [ + ^ self + possibilities: aCollectionOfObjects + label: aLabelBlock + action: anAction + selectedObject: anObjectOrNil + choosingText: aText + description: nil +] + +{ #category : #'instance creation' } +MDLMenuButtonWidget class >> possibilities: aCollectionOfObjects label: aLabelBlock action: anAction selectedObject: anObjectOrNil choosingText: aText description: aDescriptionValuable [ + ^ self new + choosingText: aText; + textBlock: aLabelBlock; + selectedObject: anObjectOrNil; + description: aDescriptionValuable; + action: anAction; + objectsPossibilities: aCollectionOfObjects; + yourself +] + +{ #category : #accessing } +MDLMenuButtonWidget >> action [ + ^ action +] + +{ #category : #accessing } +MDLMenuButtonWidget >> action: anObject [ + action := anObject +] + +{ #category : #private } +MDLMenuButtonWidget >> actionWith: anObject [ + self action ifNotNil: [ :block | block value: anObject] +] + +{ #category : #accessing } +MDLMenuButtonWidget >> buttonContent [ + ^ buttonContent ifNil: [ buttonContent := 'choose' ] +] + +{ #category : #accessing } +MDLMenuButtonWidget >> buttonContent: aBlockOrString [ + buttonContent := aBlockOrString +] + +{ #category : #accessing } +MDLMenuButtonWidget >> choosingText [ + "This method is to keep backward compatibility with old API. This might be suppress with the next major release." + + self buttonContent isString ifTrue: [ ^ self buttonContent ]. + + self error: 'This button was not configured to render a string but was configured with a block' +] + +{ #category : #accessing } +MDLMenuButtonWidget >> choosingText: aString [ + "This method is to keep backward compatibility with old API. This might be suppress with the next major release." + + self buttonContent: aString +] + +{ #category : #accessing } +MDLMenuButtonWidget >> description [ + ^ description +] + +{ #category : #accessing } +MDLMenuButtonWidget >> description: anObject [ + description := anObject +] + +{ #category : #options } +MDLMenuButtonWidget >> descriptionAtBottom [ + "Sets the description of the menu at its bottom." + self descriptionPosition: #bottom +] + +{ #category : #options } +MDLMenuButtonWidget >> descriptionAtLeft [ + "Sets the description of the menu at its left." + self descriptionPosition: #left +] + +{ #category : #options } +MDLMenuButtonWidget >> descriptionAtRight [ + "Sets the description of the menu at its right." + self descriptionPosition: #right +] + +{ #category : #options } +MDLMenuButtonWidget >> descriptionAtTop [ + "Sets the description of the menu at its top." + self descriptionPosition: #top +] + +{ #category : #accessing } +MDLMenuButtonWidget >> descriptionPosition [ + ^ descriptionPosition ifNil: [ descriptionPosition := #bottom ] +] + +{ #category : #accessing } +MDLMenuButtonWidget >> descriptionPosition: anObject [ + descriptionPosition := anObject +] + +{ #category : #private } +MDLMenuButtonWidget >> labelFor: anObject [ + ^ self textBlock ifNil: [ anObject asString ] ifNotNil: [ :tb | tb cull: anObject ] +] + +{ #category : #accessing } +MDLMenuButtonWidget >> objectsPossibilities [ + ^ objectsPossibilities +] + +{ #category : #accessing } +MDLMenuButtonWidget >> objectsPossibilities: anObject [ + objectsPossibilities := anObject +] + +{ #category : #accessing } +MDLMenuButtonWidget >> objectsPossibilitiesWithLabel [ + ^ (self objectsPossibilities collect: [ :anObject | (self labelFor: anObject) -> anObject ]) sorted: self sortBlock +] + +{ #category : #rendering } +MDLMenuButtonWidget >> renderButtonContentOn: html [ + self buttonContent isString + ifTrue: [ html render: self buttonContent ] + ifFalse: [ self buttonContent cull: html ] +] + +{ #category : #rendering } +MDLMenuButtonWidget >> renderButtonOn: html [ + html div + id: self id; + class: 'menuButtonWidgetButton mdl-button mdl-js-button menuButtonWidgetButton'; + disabled: self objectsPossibilities isEmpty; + with: [ self selectedObject + ifNil: [ self renderButtonContentOn: html ] + ifNotNil: [ :anObject | html text: (self labelFor: anObject) ]. + html mdlIcon: 'arrow_drop_down' ] +] + +{ #category : #rendering } +MDLMenuButtonWidget >> renderContentOn: html [ + self ensureId: html. + self renderButtonOn: html. + self renderMenuOn: html. + self renderTooltipOn: html. +] + +{ #category : #rendering } +MDLMenuButtonWidget >> renderMenuItemOn: html withAssociation: anAssociation [ + html + mdlMenuItem: [ + html anchor + callback: [ self actionWith: anAssociation value ]; + with: [ html text: anAssociation key ] ] +] + +{ #category : #rendering } +MDLMenuButtonWidget >> renderMenuOn: html [ + html mdlMenu + bottomLeft; + for: self id; + class: 'menuButtonWidgetMenu'; + with: [ self objectsPossibilitiesWithLabel do: [ :anAssociation | self renderMenuItemOn: html withAssociation: anAssociation ] ] +] + +{ #category : #rendering } +MDLMenuButtonWidget >> renderTooltipOn: html [ + self description ifNil: [ ^ self ]. + + html mdlTooltip + for: self id; + large; + position: self descriptionPosition; + with: self description +] + +{ #category : #accessing } +MDLMenuButtonWidget >> selectedObject [ + ^ selectedObject value +] + +{ #category : #accessing } +MDLMenuButtonWidget >> selectedObject: anObject [ + selectedObject := anObject +] + +{ #category : #accessing } +MDLMenuButtonWidget >> sortBlock [ + ^ sortBlock ifNil: [ sortBlock := [ :a :b | a <= b ] ] +] + +{ #category : #accessing } +MDLMenuButtonWidget >> sortBlock: anObject [ + sortBlock := anObject +] + +{ #category : #accessing } +MDLMenuButtonWidget >> textBlock [ + ^ textBlock +] + +{ #category : #accessing } +MDLMenuButtonWidget >> textBlock: anObject [ + textBlock := anObject +] diff --git a/src/Material-Design-Lite-Widgets/MDLMiniFooterLinksList.class.st b/src/Material-Design-Lite-Widgets/MDLMiniFooterLinksList.class.st index 49d94b2d..2008fe7e 100644 --- a/src/Material-Design-Lite-Widgets/MDLMiniFooterLinksList.class.st +++ b/src/Material-Design-Lite-Widgets/MDLMiniFooterLinksList.class.st @@ -1,11 +1,11 @@ -Class { - #name : #MDLMiniFooterLinksList, - #superclass : #MDLAbstractFooterLinksList, - #category : 'Material-Design-Lite-Widgets-Footer' -} - -{ #category : #'as yet unclassified' } -MDLMiniFooterLinksList >> renderLinksListOn: html [ - html mdlMiniFooterLinkList: [ - self renderLinksOn: html ] -] +Class { + #name : #MDLMiniFooterLinksList, + #superclass : #MDLAbstractFooterLinksList, + #category : 'Material-Design-Lite-Widgets-Footer' +} + +{ #category : #'as yet unclassified' } +MDLMiniFooterLinksList >> renderLinksListOn: html [ + html mdlMiniFooterLinkList: [ + self renderLinksOn: html ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLNavigationLinkWithIconComponent.class.st b/src/Material-Design-Lite-Widgets/MDLNavigationLinkWithIconComponent.class.st index efb4a265..7ca8131d 100644 --- a/src/Material-Design-Lite-Widgets/MDLNavigationLinkWithIconComponent.class.st +++ b/src/Material-Design-Lite-Widgets/MDLNavigationLinkWithIconComponent.class.st @@ -1,54 +1,54 @@ -Class { - #name : #MDLNavigationLinkWithIconComponent, - #superclass : #WAComponent, - #instVars : [ - 'icon', - 'label', - 'callback', - 'iconUrl' - ], - #category : 'Material-Design-Lite-Widgets' -} - -{ #category : #accessing } -MDLNavigationLinkWithIconComponent >> callback [ - ^ callback -] - -{ #category : #accessing } -MDLNavigationLinkWithIconComponent >> callback: anObject [ - callback := anObject -] - -{ #category : #accessing } -MDLNavigationLinkWithIconComponent >> icon [ - ^ icon -] - -{ #category : #accessing } -MDLNavigationLinkWithIconComponent >> iconUrl: anObject [ - iconUrl := anObject -] - -{ #category : #accessing } -MDLNavigationLinkWithIconComponent >> label [ - ^ label -] - -{ #category : #accessing } -MDLNavigationLinkWithIconComponent >> label: anObject [ - label := anObject -] - -{ #category : #rendering } -MDLNavigationLinkWithIconComponent >> renderContentOn: html [ - html mdlNavigationLink - style: 'margin: 8px 16px'; - callback: callback; - with: [ html - div: [ html image - url: (iconUrl);" - url: (MDLDemoLibrary urlOf: icon);" - style: 'height: 46px; width: 46px; margin: 0px 10px;'. - html span: label ] ] -] +Class { + #name : #MDLNavigationLinkWithIconComponent, + #superclass : #WAComponent, + #instVars : [ + 'icon', + 'label', + 'callback', + 'iconUrl' + ], + #category : 'Material-Design-Lite-Widgets' +} + +{ #category : #accessing } +MDLNavigationLinkWithIconComponent >> callback [ + ^ callback +] + +{ #category : #accessing } +MDLNavigationLinkWithIconComponent >> callback: anObject [ + callback := anObject +] + +{ #category : #accessing } +MDLNavigationLinkWithIconComponent >> icon [ + ^ icon +] + +{ #category : #accessing } +MDLNavigationLinkWithIconComponent >> iconUrl: anObject [ + iconUrl := anObject +] + +{ #category : #accessing } +MDLNavigationLinkWithIconComponent >> label [ + ^ label +] + +{ #category : #accessing } +MDLNavigationLinkWithIconComponent >> label: anObject [ + label := anObject +] + +{ #category : #rendering } +MDLNavigationLinkWithIconComponent >> renderContentOn: html [ + html mdlNavigationLink + style: 'margin: 8px 16px'; + callback: callback; + with: [ html + div: [ html image + url: (iconUrl);" + url: (MDLDemoLibrary urlOf: icon);" + style: 'height: 46px; width: 46px; margin: 0px 10px;'. + html span: label ] ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLNestedList.class.st b/src/Material-Design-Lite-Widgets/MDLNestedList.class.st index 6c438ae2..f69a84a0 100644 --- a/src/Material-Design-Lite-Widgets/MDLNestedList.class.st +++ b/src/Material-Design-Lite-Widgets/MDLNestedList.class.st @@ -1,651 +1,651 @@ -" -I am a component use to display nicely a list of elements. -I am also able to display nested list as a tree. - -Description ------------------- - -I display a list of elements and I manage most of the css needed to make a good rendering. -For the icon check MDLListIconComponent or give any component you want. - -For more info you can test the demo. - -Public API and Key Messages ------------------- - -- #actionBlock: aBlock Allow to set an action to execute on click -- #elements: aCollection Is the list of elements to display -- #children: aBlock Return for each element his childrens -- #format: aBlock Is a block that take an element and return the element with the right format -- #selectedEntity: anElement If the element in parameter is in the list, it zill be highlighted -- #helpBlock: aBlock Allow to add a fly by help on elements -- #iconBlock: aBlock Allow to add an icon on each line - -Example ------------------- - - (SYNListComponent elements: #(1 34 56 89) children: [ :number | number even ifTrue: [ {(number + 1) . (number + 3) } ] ifFalse: [ #() ] ] ]) - actionBlock: [ :elem | Transcript crShow: elem asString ]; - format: [ :elem | elem asString , '%' ]; - selectedEntity: 34; - yourself - -Internal Representation and Key Implementation Points. ------------------- - - Instance Variables - actionBlock: A block executed when an element is selected - children: A block that return the list of children of an element - elements: A collection of elements to display - format: A block executed to format an element - selectedEntity: An element that need to be highlighted in the list - helpBlock: A block that return an optional fly-by-felp for an element - iconBlock: A block thet return an optional SYNListIconComponent for a line of the list -" -Class { - #name : #MDLNestedList, - #superclass : #MDLWidget, - #instVars : [ - 'elements', - 'entryCustomizationHook', - 'filteredElements', - 'selectedEntity', - 'dragAndDropBlock', - 'displayResearchField', - 'displayResearchFilter', - 'filter', - 'listStyle', - 'onLoadHook', - 'listMaxSize', - 'obtainedTreesCache', - 'strategy' - ], - #category : #'Material-Design-Lite-Widgets-List' -} - -{ #category : #'instance creation' } -MDLNestedList class >> elements: aCollection [ - ^ self new - elements: aCollection; - yourself -] - -{ #category : #'instance creation' } -MDLNestedList class >> elements: aCollection children: aBlockOrSymbole [ - ^ (self elements: aCollection) - childrenBlock: aBlockOrSymbole; - yourself -] - -{ #category : #accessing } -MDLNestedList >> actionBlock [ - ^ self strategy actionBlock -] - -{ #category : #accessing } -MDLNestedList >> actionBlock: aBlock [ - self - assert: aBlock argumentCount = 1 - description: - 'This block must take one argument; it will be the clicked entity in the list'. - self strategy actionBlock: aBlock -] - -{ #category : #private } -MDLNestedList >> at: anInteger ifPresent: aBlockClosure [ - aBlockClosure value: (self filteredElements at: anInteger) -] - -{ #category : #accessing } -MDLNestedList >> beCompact [ - self listStyle: #compact -] - -{ #category : #accessing } -MDLNestedList >> beStandard [ - self listStyle: #standard -] - -{ #category : #accessing } -MDLNestedList >> children: aBlockOrSymbol [ - self childrenBlock: aBlockOrSymbol -] - -{ #category : #accessing } -MDLNestedList >> childrenBlock [ - ^ self strategy childrenBlock - ifNil: [ self strategy childrenBlock: [ :item | #() ]. - self strategy childrenBlock ] -] - -{ #category : #accessing } -MDLNestedList >> childrenBlock: anObject [ - self strategy childrenBlock: anObject -] - -{ #category : #accessing } -MDLNestedList >> childrenSortBlock [ - ^ self strategy childrenSortBlock -] - -{ #category : #accessing } -MDLNestedList >> childrenSortBlock: aBlock [ - self strategy childrenSortBlock: aBlock -] - -{ #category : #javascript } -MDLNestedList >> defineChildrenCallbackOn: aDiv [ - ^ aDiv - storeCallback: - (WAValueCallback - on: [ :intervalRequest | - self requestContext - respond: [ :response | - self - printSublistFor: intervalRequest - context: aDiv canvas context - on: - (response - doNotCache; - contentType: WAMimeType textHtml; - stream) ] ]) -] - -{ #category : #javascript } -MDLNestedList >> defineScrollCallbackOn: aDiv [ - ^ aDiv - storeCallback: - (WAValueCallback - on: [ :intervalRequest | - | interval | - interval := $: split: intervalRequest. - self requestContext - respond: [ :response | - self - printHtmlForElementsFrom: interval first asNumber - to: interval last asNumber - context: aDiv canvas context - on: - (response - doNotCache; - contentType: WAMimeType textHtml; - stream) ] ]) -] - -{ #category : #accessing } -MDLNestedList >> displayResearchField [ - ^ displayResearchField -] - -{ #category : #accessing } -MDLNestedList >> displayResearchField: aBoolean [ - displayResearchField := aBoolean -] - -{ #category : #accessing } -MDLNestedList >> displayResearchFilter [ - ^ displayResearchFilter -] - -{ #category : #accessing } -MDLNestedList >> displayResearchFilter: aFilter [ - aFilter - ifEmpty: [ - displayResearchFilter := nil. - filteredElements := #() ] - ifNotEmpty: [ - displayResearchFilter := aFilter. - filteredElements := self filter - selectMatchingFrom: self elements - format: self format - with: self displayResearchFilter ] -] - -{ #category : #accessing } -MDLNestedList >> dragAndDropBlock [ - ^ dragAndDropBlock -] - -{ #category : #accessing } -MDLNestedList >> dragAndDropBlock: anObject [ - dragAndDropBlock := anObject -] - -{ #category : #draggable } -MDLNestedList >> draggableMechanism: html forDiv: div [ - self hasDraggableItems - ifTrue: [ - html - script: - (self - draggableScript: html actionUrl - cb: - (div - storeCallback: - (WAValueCallback - on: [ :drag | - | dragValues | - dragValues := drag substrings: ';'. - self dragAndDropBlock - value: (self obtainElementForPath: dragValues first) - value: (self obtainElementForPath: dragValues second) ]))) ] -] - -{ #category : #draggable } -MDLNestedList >> draggableScript:url cb: draggableCb [ - ^ 'function dragListItem(ev, index) { - ev.dataTransfer.setData("sourceIndex", index); -} - - -function dropListItem(ev, index){ - var source = ev.dataTransfer.getData("sourceIndex"); - var target = index; - if(source == target) console.log("Sleep"); - else post("' , url asString , '",{' , draggableCb - , - ': source + ";" + target});; -}' -] - -{ #category : #accessing } -MDLNestedList >> elements [ - ^ elements value -] - -{ #category : #accessing } -MDLNestedList >> elements: anObject [ - elements := anObject. - "reinitialize the filter when list change" - self displayResearchFilter: '' -] - -{ #category : #accessing } -MDLNestedList >> elementsDisplayList [ - | start overflow | - ^ self filteredElements size <= self listMaxSize - ifTrue: [ self filteredElements ] - ifFalse: [ start := self indexOfRootElementContainingSelectedEntity - (self listMaxSize / 2) max: 1. - overflow := 0 max: start + self listMaxSize - self filteredElements size. - self filteredElements copyFrom: start - overflow to: start + self listMaxSize - 1 - overflow ] -] - -{ #category : #accessing } -MDLNestedList >> entryCustomizationHook [ - ^ entryCustomizationHook -] - -{ #category : #accessing } -MDLNestedList >> entryCustomizationHook: anObject [ - entryCustomizationHook := anObject -] - -{ #category : #accessing } -MDLNestedList >> filter [ - ^ filter -] - -{ #category : #accessing } -MDLNestedList >> filter: anObject [ - filter := anObject -] - -{ #category : #accessing } -MDLNestedList >> filterInsensitiveBeginsWith [ - self filter: MDLInsensitiveBeginsWithFilter -] - -{ #category : #accessing } -MDLNestedList >> filterInsensitiveSubstring [ - self filter: MDLInsensitiveSubstringFilter -] - -{ #category : #accessing } -MDLNestedList >> filterPseudoRegex [ - self filter: MDLPseudoRegexFilter -] - -{ #category : #accessing } -MDLNestedList >> filterSensitiveBeginsWith [ - self filter: MDLBeginsWithFilter -] - -{ #category : #accessing } -MDLNestedList >> filterSubstring [ - self filter: MDLSubstringFilter -] - -{ #category : #accessing } -MDLNestedList >> filteredElements [ - ^ self displayResearchFilter ifNil: [ self elements ] ifNotNil: [ filteredElements ] -] - -{ #category : #accessing } -MDLNestedList >> format [ - ^ self strategy format ifNil: [ #asString ] -] - -{ #category : #accessing } -MDLNestedList >> format: anObject [ - self strategy format: anObject -] - -{ #category : #testing } -MDLNestedList >> hasDraggableItems [ - ^ self dragAndDropBlock notNil -] - -{ #category : #accessing } -MDLNestedList >> helpBlock [ - ^ self strategy helpBlock -] - -{ #category : #accessing } -MDLNestedList >> helpBlock: anObject [ - self strategy helpBlock: anObject -] - -{ #category : #accessing } -MDLNestedList >> iconBlock [ - ^ self strategy iconBlock -] - -{ #category : #accessing } -MDLNestedList >> iconBlock: anObject [ - self strategy iconBlock: anObject -] - -{ #category : #private } -MDLNestedList >> idFor: aSymbol [ - ^ aSymbol, self id -] - -{ #category : #accessing } -MDLNestedList >> indexOfRootElementContainingSelectedEntity [ - self selectedEntity ifNil: [ ^ 0 ]. - ^ self filteredElements - indexOf: self selectedEntity - ifAbsent: [ self filteredElements - detect: [ :element | self isIncludingSelectedChildren: element ] - ifFound: [ :element | self filteredElements indexOf: element ] - ifNone: [ "The selected element is not at all in the tree" 1 ] ] -] - -{ #category : #initialization } -MDLNestedList >> initialize [ - super initialize. - self - listMaxSize: 150; - displayResearchField: false; - isJsAction: false; - listStyle: #standard; - filterInsensitiveBeginsWith; - onLoadHook: 'componentHandler.upgradeDom();' -] - -{ #category : #positionning } -MDLNestedList >> isIncludingSelectedChildren: anElement [ - ^ (self childrenBlock value: anElement) anySatisfy: [ :aChildren | aChildren = selectedEntity or: [ self isIncludingSelectedChildren: aChildren ] ] -] - -{ #category : #accessing } -MDLNestedList >> isJsAction [ - ^ self strategy isJsAction -] - -{ #category : #accessing } -MDLNestedList >> isJsAction: anObject [ - self strategy isJsAction: anObject -] - -{ #category : #javascript } -MDLNestedList >> jsOnLoadHook [ - ^ self onLoadHook js -] - -{ #category : #accessing } -MDLNestedList >> listElementsDynamicalLoadingStep [ - "It is the number of elements asked in ajax to the server when user scroll" - ^ self listMaxSize / 5 -] - -{ #category : #accessing } -MDLNestedList >> listMaxSize [ - ^ listMaxSize -] - -{ #category : #accessing } -MDLNestedList >> listMaxSize: anObject [ - listMaxSize := anObject -] - -{ #category : #accessing } -MDLNestedList >> listStyle [ - ^ listStyle -] - -{ #category : #accessing } -MDLNestedList >> listStyle: anObject [ - listStyle := anObject -] - -{ #category : #private } -MDLNestedList >> obtainElementForPath: aPath [ - | path | - path := $: split: aPath. - ^ (path allButLast - inject: self filteredElements - into: [ :elemts :anIndex | - | res | - res := self childrenBlock value: (elemts at: anIndex asNumber). - self childrenSortBlock ifNil: [ res ] ifNotNil: [ :sortBlock | res sorted: sortBlock ] ]) at: path last asNumber -] - -{ #category : #private } -MDLNestedList >> obtainTreeFor: anElement [ - ^ obtainedTreesCache at: anElement ifAbsentPut: [ MDLNestedListTreeNode list: self element: anElement ] -] - -{ #category : #accessing } -MDLNestedList >> onClickJs: anActionBlock [ - self actionBlock: anActionBlock. - self isJsAction: true -] - -{ #category : #accessing } -MDLNestedList >> onLoadHook [ - ^ onLoadHook -] - -{ #category : #accessing } -MDLNestedList >> onLoadHook: anObject [ - onLoadHook := anObject -] - -{ #category : #rendering } -MDLNestedList >> printHtmlForElementsFrom: start to: end context: aContext on: stream [ - self - printResultOf: [ :html | - (start <= self filteredElements size and: [ end >= 1 ]) - ifTrue: [ - self filteredElements - from: (start max: 1) - to: (end min: self filteredElements size) - do: [ :anElement | - self - renderListTree: (self obtainTreeFor: anElement) - index: (self filteredElements indexOf: anElement) - indentedBy: 1 - on: html ] ] ] - context: aContext - on: stream -] - -{ #category : #rendering } -MDLNestedList >> printResultOf: aBlock context: aContext on: stream [ - | document | - document := (WAHtmlDocument on: stream codec: GRNullCodec new) - scriptGenerator: WADefaultScriptGenerator new; - yourself. - aContext document: document. - (WAHtmlCanvas context: aContext) - render: aBlock; - flush. - document scriptGenerator closeOn: document -] - -{ #category : #rendering } -MDLNestedList >> printSublistFor: anIntervalRequest context: aContext on: stream [ - self - printResultOf: [ :html | - self - renderSublistOf: (self obtainTreeFor: (self obtainElementForPath: anIntervalRequest)) children - parentIndex: anIntervalRequest - indentedBy: (anIntervalRequest occurrencesOf: $:) + 1 - on: html ] - context: aContext - on: stream -] - -{ #category : #rendering } -MDLNestedList >> renderContentOn: html [ - self ensureId: html. - obtainedTreesCache := IdentityDictionary new. "Reset cache while loading page." - html div - id: (self idFor: #nestedList); - class: #nestedList; - class: self listStyle; - with: [ - self renderFilterFieldOn: html. - html div - id: (self idFor: #listContent); - class: #listContent; - class: #withSearch if: self displayResearchField; - with: [ self renderListOn: html ] ] -] - -{ #category : #researchField } -MDLNestedList >> renderFilterFieldOn: html [ - self displayResearchField ifFalse: [ ^ self ]. - - html div - class: #listResearchField; - with: [ html - mdlTextFieldContainer: [ html mdlTextFieldLabel - for: (self idFor: #researchFieldId); - with: 'Search'. - html mdlTextFieldInput - id: (self idFor: #researchFieldId); - type: 'text'; - value: self displayResearchFilter; - onChange: - (html jQuery ajax - callback: [ :filt | self displayResearchFilter: filt ] value: 'event.target.value' js; - onComplete: - ((html jQuery: '#' , (self idFor: #listContainer)) parent load - html: [ :htm | self renderListOn: htm ]; - onComplete: (self jsOnLoadHook , ('scrollToSelection();defineExpandable();stopSpinnerOf("' , (self idFor: #researchFieldId) , '")') js))) ]. - html mdlSpinner singleColor ] -] - -{ #category : #rendering } -MDLNestedList >> renderHelpOf: anItem at: anId on: html [ - | helpText | - (self helpBlock isNil - or: [ self helpBlock argumentCount = 1 and: [ (helpText := self helpBlock value: anItem) isEmptyOrNil ] ]) - ifTrue: [ ^ self ]. - - html mdlTooltip - large; - for: anId; - with: - (self helpBlock argumentCount = 1 - ifTrue: [ helpText ] - ifFalse: [ self helpBlock mdlCull: anItem cull: html ]) -] - -{ #category : #rendering } -MDLNestedList >> renderListOn: html [ - | div | - div := html div - id: (self idFor: #listContainer); - class: #listContainer. - self setDataForCallBackFor: div html: html. - div - with: [ - | elementsToDisplay firstElementIndex | - elementsToDisplay := self elementsDisplayList. - firstElementIndex := self filteredElements - indexOf: (elementsToDisplay ifEmpty: [ nil ] ifNotEmpty: [ :coll | coll first ]). - html unorderedList - id: (self idFor: #expList); - class: #expList; - with: [ - elementsToDisplay - doWithIndex: [ :item :index | - self strategy - renderListTree: (self obtainTreeFor: item) - index: index + firstElementIndex - 1 - indentedBy: 1 - on: html ] ] ]. - self draggableMechanism: html forDiv: div -] - -{ #category : #accessing } -MDLNestedList >> rightIconBlock [ - ^ self strategy rightIconBlock -] - -{ #category : #accessing } -MDLNestedList >> rightIconBlock: anObject [ - self strategy rightIconBlock: anObject -] - -{ #category : #accessing } -MDLNestedList >> selectedEntity [ - ^ selectedEntity -] - -{ #category : #accessing } -MDLNestedList >> selectedEntity: anObject [ - selectedEntity := anObject -] - -{ #category : #hooks } -MDLNestedList >> setAjaxStrategy [ - self strategy: self strategy asAjaxStrategy -] - -{ #category : #javascript } -MDLNestedList >> setDataForCallBackFor: div html: html [ - div - attributeAt: #'data-url' put: html actionUrl asString; - attributeAt: #'data-cbId' put: (self defineScrollCallbackOn: div) asString; - attributeAt: #'data-childrenCbId' put: (self defineChildrenCallbackOn: div) asString; - attributeAt: #'data-listMaxSize' put: self listMaxSize asString; - attributeAt: #'data-lastIndexAsked' put: (self filteredElements indexOf: self selectedEntity ifAbsent: 1) asString; - attributeAt: #'data-onLoadHook' put: self jsOnLoadHook; - attributeAt: #'data-loadingstep' put: self listElementsDynamicalLoadingStep asString -] - -{ #category : #hooks } -MDLNestedList >> states [ - self flag: #BECAREFUL. "I am absolutly not sure we want to do this. I let it to try but it might be removed." - ^ Array with: self -] - -{ #category : #accessing } -MDLNestedList >> strategy [ - ^ strategy - ifNil: [ strategy := MDLNestedListItemRenderAnchorStrategy new ] -] - -{ #category : #accessing } -MDLNestedList >> strategy: anObject [ - strategy := anObject -] - -{ #category : #researchField } -MDLNestedList >> withResearchField [ - self displayResearchField: true -] +" +I am a component use to display nicely a list of elements. +I am also able to display nested list as a tree. + +Description +------------------ + +I display a list of elements and I manage most of the css needed to make a good rendering. +For the icon check MDLListIconComponent or give any component you want. + +For more info you can test the demo. + +Public API and Key Messages +------------------ + +- #actionBlock: aBlock Allow to set an action to execute on click +- #elements: aCollection Is the list of elements to display +- #children: aBlock Return for each element his childrens +- #format: aBlock Is a block that take an element and return the element with the right format +- #selectedEntity: anElement If the element in parameter is in the list, it zill be highlighted +- #helpBlock: aBlock Allow to add a fly by help on elements +- #iconBlock: aBlock Allow to add an icon on each line + +Example +------------------ + + (SYNListComponent elements: #(1 34 56 89) children: [ :number | number even ifTrue: [ {(number + 1) . (number + 3) } ] ifFalse: [ #() ] ] ]) + actionBlock: [ :elem | Transcript crShow: elem asString ]; + format: [ :elem | elem asString , '%' ]; + selectedEntity: 34; + yourself + +Internal Representation and Key Implementation Points. +------------------ + + Instance Variables + actionBlock: A block executed when an element is selected + children: A block that return the list of children of an element + elements: A collection of elements to display + format: A block executed to format an element + selectedEntity: An element that need to be highlighted in the list + helpBlock: A block that return an optional fly-by-felp for an element + iconBlock: A block thet return an optional SYNListIconComponent for a line of the list +" +Class { + #name : #MDLNestedList, + #superclass : #MDLWidget, + #instVars : [ + 'elements', + 'entryCustomizationHook', + 'filteredElements', + 'selectedEntity', + 'dragAndDropBlock', + 'displayResearchField', + 'displayResearchFilter', + 'filter', + 'listStyle', + 'onLoadHook', + 'listMaxSize', + 'obtainedTreesCache', + 'strategy' + ], + #category : #'Material-Design-Lite-Widgets-List' +} + +{ #category : #'instance creation' } +MDLNestedList class >> elements: aCollection [ + ^ self new + elements: aCollection; + yourself +] + +{ #category : #'instance creation' } +MDLNestedList class >> elements: aCollection children: aBlockOrSymbole [ + ^ (self elements: aCollection) + childrenBlock: aBlockOrSymbole; + yourself +] + +{ #category : #accessing } +MDLNestedList >> actionBlock [ + ^ self strategy actionBlock +] + +{ #category : #accessing } +MDLNestedList >> actionBlock: aBlock [ + self + assert: aBlock argumentCount = 1 + description: + 'This block must take one argument; it will be the clicked entity in the list'. + self strategy actionBlock: aBlock +] + +{ #category : #private } +MDLNestedList >> at: anInteger ifPresent: aBlockClosure [ + aBlockClosure value: (self filteredElements at: anInteger) +] + +{ #category : #accessing } +MDLNestedList >> beCompact [ + self listStyle: #compact +] + +{ #category : #accessing } +MDLNestedList >> beStandard [ + self listStyle: #standard +] + +{ #category : #accessing } +MDLNestedList >> children: aBlockOrSymbol [ + self childrenBlock: aBlockOrSymbol +] + +{ #category : #accessing } +MDLNestedList >> childrenBlock [ + ^ self strategy childrenBlock + ifNil: [ self strategy childrenBlock: [ :item | #() ]. + self strategy childrenBlock ] +] + +{ #category : #accessing } +MDLNestedList >> childrenBlock: anObject [ + self strategy childrenBlock: anObject +] + +{ #category : #accessing } +MDLNestedList >> childrenSortBlock [ + ^ self strategy childrenSortBlock +] + +{ #category : #accessing } +MDLNestedList >> childrenSortBlock: aBlock [ + self strategy childrenSortBlock: aBlock +] + +{ #category : #javascript } +MDLNestedList >> defineChildrenCallbackOn: aDiv [ + ^ aDiv + storeCallback: + (WAValueCallback + on: [ :intervalRequest | + self requestContext + respond: [ :response | + self + printSublistFor: intervalRequest + context: aDiv canvas context + on: + (response + doNotCache; + contentType: WAMimeType textHtml; + stream) ] ]) +] + +{ #category : #javascript } +MDLNestedList >> defineScrollCallbackOn: aDiv [ + ^ aDiv + storeCallback: + (WAValueCallback + on: [ :intervalRequest | + | interval | + interval := $: split: intervalRequest. + self requestContext + respond: [ :response | + self + printHtmlForElementsFrom: interval first asNumber + to: interval last asNumber + context: aDiv canvas context + on: + (response + doNotCache; + contentType: WAMimeType textHtml; + stream) ] ]) +] + +{ #category : #accessing } +MDLNestedList >> displayResearchField [ + ^ displayResearchField +] + +{ #category : #accessing } +MDLNestedList >> displayResearchField: aBoolean [ + displayResearchField := aBoolean +] + +{ #category : #accessing } +MDLNestedList >> displayResearchFilter [ + ^ displayResearchFilter +] + +{ #category : #accessing } +MDLNestedList >> displayResearchFilter: aFilter [ + aFilter + ifEmpty: [ + displayResearchFilter := nil. + filteredElements := #() ] + ifNotEmpty: [ + displayResearchFilter := aFilter. + filteredElements := self filter + selectMatchingFrom: self elements + format: self format + with: self displayResearchFilter ] +] + +{ #category : #accessing } +MDLNestedList >> dragAndDropBlock [ + ^ dragAndDropBlock +] + +{ #category : #accessing } +MDLNestedList >> dragAndDropBlock: anObject [ + dragAndDropBlock := anObject +] + +{ #category : #draggable } +MDLNestedList >> draggableMechanism: html forDiv: div [ + self hasDraggableItems + ifTrue: [ + html + script: + (self + draggableScript: html actionUrl + cb: + (div + storeCallback: + (WAValueCallback + on: [ :drag | + | dragValues | + dragValues := drag substrings: ';'. + self dragAndDropBlock + value: (self obtainElementForPath: dragValues first) + value: (self obtainElementForPath: dragValues second) ]))) ] +] + +{ #category : #draggable } +MDLNestedList >> draggableScript:url cb: draggableCb [ + ^ 'function dragListItem(ev, index) { + ev.dataTransfer.setData("sourceIndex", index); +} + + +function dropListItem(ev, index){ + var source = ev.dataTransfer.getData("sourceIndex"); + var target = index; + if(source == target) console.log("Sleep"); + else post("' , url asString , '",{' , draggableCb + , + ': source + ";" + target});; +}' +] + +{ #category : #accessing } +MDLNestedList >> elements [ + ^ elements value +] + +{ #category : #accessing } +MDLNestedList >> elements: anObject [ + elements := anObject. + "reinitialize the filter when list change" + self displayResearchFilter: '' +] + +{ #category : #accessing } +MDLNestedList >> elementsDisplayList [ + | start overflow | + ^ self filteredElements size <= self listMaxSize + ifTrue: [ self filteredElements ] + ifFalse: [ start := self indexOfRootElementContainingSelectedEntity - (self listMaxSize / 2) max: 1. + overflow := 0 max: start + self listMaxSize - self filteredElements size. + self filteredElements copyFrom: start - overflow to: start + self listMaxSize - 1 - overflow ] +] + +{ #category : #accessing } +MDLNestedList >> entryCustomizationHook [ + ^ entryCustomizationHook +] + +{ #category : #accessing } +MDLNestedList >> entryCustomizationHook: anObject [ + entryCustomizationHook := anObject +] + +{ #category : #accessing } +MDLNestedList >> filter [ + ^ filter +] + +{ #category : #accessing } +MDLNestedList >> filter: anObject [ + filter := anObject +] + +{ #category : #accessing } +MDLNestedList >> filterInsensitiveBeginsWith [ + self filter: MDLInsensitiveBeginsWithFilter +] + +{ #category : #accessing } +MDLNestedList >> filterInsensitiveSubstring [ + self filter: MDLInsensitiveSubstringFilter +] + +{ #category : #accessing } +MDLNestedList >> filterPseudoRegex [ + self filter: MDLPseudoRegexFilter +] + +{ #category : #accessing } +MDLNestedList >> filterSensitiveBeginsWith [ + self filter: MDLBeginsWithFilter +] + +{ #category : #accessing } +MDLNestedList >> filterSubstring [ + self filter: MDLSubstringFilter +] + +{ #category : #accessing } +MDLNestedList >> filteredElements [ + ^ self displayResearchFilter ifNil: [ self elements ] ifNotNil: [ filteredElements ] +] + +{ #category : #accessing } +MDLNestedList >> format [ + ^ self strategy format ifNil: [ #asString ] +] + +{ #category : #accessing } +MDLNestedList >> format: anObject [ + self strategy format: anObject +] + +{ #category : #testing } +MDLNestedList >> hasDraggableItems [ + ^ self dragAndDropBlock notNil +] + +{ #category : #accessing } +MDLNestedList >> helpBlock [ + ^ self strategy helpBlock +] + +{ #category : #accessing } +MDLNestedList >> helpBlock: anObject [ + self strategy helpBlock: anObject +] + +{ #category : #accessing } +MDLNestedList >> iconBlock [ + ^ self strategy iconBlock +] + +{ #category : #accessing } +MDLNestedList >> iconBlock: anObject [ + self strategy iconBlock: anObject +] + +{ #category : #private } +MDLNestedList >> idFor: aSymbol [ + ^ aSymbol, self id +] + +{ #category : #accessing } +MDLNestedList >> indexOfRootElementContainingSelectedEntity [ + self selectedEntity ifNil: [ ^ 0 ]. + ^ self filteredElements + indexOf: self selectedEntity + ifAbsent: [ self filteredElements + detect: [ :element | self isIncludingSelectedChildren: element ] + ifFound: [ :element | self filteredElements indexOf: element ] + ifNone: [ "The selected element is not at all in the tree" 1 ] ] +] + +{ #category : #initialization } +MDLNestedList >> initialize [ + super initialize. + self + listMaxSize: 150; + displayResearchField: false; + isJsAction: false; + listStyle: #standard; + filterInsensitiveBeginsWith; + onLoadHook: 'componentHandler.upgradeDom();' +] + +{ #category : #positionning } +MDLNestedList >> isIncludingSelectedChildren: anElement [ + ^ (self childrenBlock value: anElement) anySatisfy: [ :aChildren | aChildren = selectedEntity or: [ self isIncludingSelectedChildren: aChildren ] ] +] + +{ #category : #accessing } +MDLNestedList >> isJsAction [ + ^ self strategy isJsAction +] + +{ #category : #accessing } +MDLNestedList >> isJsAction: anObject [ + self strategy isJsAction: anObject +] + +{ #category : #javascript } +MDLNestedList >> jsOnLoadHook [ + ^ self onLoadHook js +] + +{ #category : #accessing } +MDLNestedList >> listElementsDynamicalLoadingStep [ + "It is the number of elements asked in ajax to the server when user scroll" + ^ self listMaxSize / 5 +] + +{ #category : #accessing } +MDLNestedList >> listMaxSize [ + ^ listMaxSize +] + +{ #category : #accessing } +MDLNestedList >> listMaxSize: anObject [ + listMaxSize := anObject +] + +{ #category : #accessing } +MDLNestedList >> listStyle [ + ^ listStyle +] + +{ #category : #accessing } +MDLNestedList >> listStyle: anObject [ + listStyle := anObject +] + +{ #category : #private } +MDLNestedList >> obtainElementForPath: aPath [ + | path | + path := $: split: aPath. + ^ (path allButLast + inject: self filteredElements + into: [ :elemts :anIndex | + | res | + res := self childrenBlock value: (elemts at: anIndex asNumber). + self childrenSortBlock ifNil: [ res ] ifNotNil: [ :sortBlock | res sorted: sortBlock ] ]) at: path last asNumber +] + +{ #category : #private } +MDLNestedList >> obtainTreeFor: anElement [ + ^ obtainedTreesCache at: anElement ifAbsentPut: [ MDLNestedListTreeNode list: self element: anElement ] +] + +{ #category : #accessing } +MDLNestedList >> onClickJs: anActionBlock [ + self actionBlock: anActionBlock. + self isJsAction: true +] + +{ #category : #accessing } +MDLNestedList >> onLoadHook [ + ^ onLoadHook +] + +{ #category : #accessing } +MDLNestedList >> onLoadHook: anObject [ + onLoadHook := anObject +] + +{ #category : #rendering } +MDLNestedList >> printHtmlForElementsFrom: start to: end context: aContext on: stream [ + self + printResultOf: [ :html | + (start <= self filteredElements size and: [ end >= 1 ]) + ifTrue: [ + self filteredElements + from: (start max: 1) + to: (end min: self filteredElements size) + do: [ :anElement | + self + renderListTree: (self obtainTreeFor: anElement) + index: (self filteredElements indexOf: anElement) + indentedBy: 1 + on: html ] ] ] + context: aContext + on: stream +] + +{ #category : #rendering } +MDLNestedList >> printResultOf: aBlock context: aContext on: stream [ + | document | + document := (WAHtmlDocument on: stream codec: GRNullCodec new) + scriptGenerator: WADefaultScriptGenerator new; + yourself. + aContext document: document. + (WAHtmlCanvas context: aContext) + render: aBlock; + flush. + document scriptGenerator closeOn: document +] + +{ #category : #rendering } +MDLNestedList >> printSublistFor: anIntervalRequest context: aContext on: stream [ + self + printResultOf: [ :html | + self + renderSublistOf: (self obtainTreeFor: (self obtainElementForPath: anIntervalRequest)) children + parentIndex: anIntervalRequest + indentedBy: (anIntervalRequest occurrencesOf: $:) + 1 + on: html ] + context: aContext + on: stream +] + +{ #category : #rendering } +MDLNestedList >> renderContentOn: html [ + self ensureId: html. + obtainedTreesCache := IdentityDictionary new. "Reset cache while loading page." + html div + id: (self idFor: #nestedList); + class: #nestedList; + class: self listStyle; + with: [ + self renderFilterFieldOn: html. + html div + id: (self idFor: #listContent); + class: #listContent; + class: #withSearch if: self displayResearchField; + with: [ self renderListOn: html ] ] +] + +{ #category : #researchField } +MDLNestedList >> renderFilterFieldOn: html [ + self displayResearchField ifFalse: [ ^ self ]. + + html div + class: #listResearchField; + with: [ html + mdlTextFieldContainer: [ html mdlTextFieldLabel + for: (self idFor: #researchFieldId); + with: 'Search'. + html mdlTextFieldInput + id: (self idFor: #researchFieldId); + type: 'text'; + value: self displayResearchFilter; + onChange: + (html jQuery ajax + callback: [ :filt | self displayResearchFilter: filt ] value: 'event.target.value' js; + onComplete: + ((html jQuery: '#' , (self idFor: #listContainer)) parent load + html: [ :htm | self renderListOn: htm ]; + onComplete: (self jsOnLoadHook , ('scrollToSelection();defineExpandable();stopSpinnerOf("' , (self idFor: #researchFieldId) , '")') js))) ]. + html mdlSpinner singleColor ] +] + +{ #category : #rendering } +MDLNestedList >> renderHelpOf: anItem at: anId on: html [ + | helpText | + (self helpBlock isNil + or: [ self helpBlock argumentCount = 1 and: [ (helpText := self helpBlock value: anItem) isEmptyOrNil ] ]) + ifTrue: [ ^ self ]. + + html mdlTooltip + large; + for: anId; + with: + (self helpBlock argumentCount = 1 + ifTrue: [ helpText ] + ifFalse: [ self helpBlock mdlCull: anItem cull: html ]) +] + +{ #category : #rendering } +MDLNestedList >> renderListOn: html [ + | div | + div := html div + id: (self idFor: #listContainer); + class: #listContainer. + self setDataForCallBackFor: div html: html. + div + with: [ + | elementsToDisplay firstElementIndex | + elementsToDisplay := self elementsDisplayList. + firstElementIndex := self filteredElements + indexOf: (elementsToDisplay ifEmpty: [ nil ] ifNotEmpty: [ :coll | coll first ]). + html unorderedList + id: (self idFor: #expList); + class: #expList; + with: [ + elementsToDisplay + doWithIndex: [ :item :index | + self strategy + renderListTree: (self obtainTreeFor: item) + index: index + firstElementIndex - 1 + indentedBy: 1 + on: html ] ] ]. + self draggableMechanism: html forDiv: div +] + +{ #category : #accessing } +MDLNestedList >> rightIconBlock [ + ^ self strategy rightIconBlock +] + +{ #category : #accessing } +MDLNestedList >> rightIconBlock: anObject [ + self strategy rightIconBlock: anObject +] + +{ #category : #accessing } +MDLNestedList >> selectedEntity [ + ^ selectedEntity +] + +{ #category : #accessing } +MDLNestedList >> selectedEntity: anObject [ + selectedEntity := anObject +] + +{ #category : #hooks } +MDLNestedList >> setAjaxStrategy [ + self strategy: self strategy asAjaxStrategy +] + +{ #category : #javascript } +MDLNestedList >> setDataForCallBackFor: div html: html [ + div + attributeAt: #'data-url' put: html actionUrl asString; + attributeAt: #'data-cbId' put: (self defineScrollCallbackOn: div) asString; + attributeAt: #'data-childrenCbId' put: (self defineChildrenCallbackOn: div) asString; + attributeAt: #'data-listMaxSize' put: self listMaxSize asString; + attributeAt: #'data-lastIndexAsked' put: (self filteredElements indexOf: self selectedEntity ifAbsent: 1) asString; + attributeAt: #'data-onLoadHook' put: self jsOnLoadHook; + attributeAt: #'data-loadingstep' put: self listElementsDynamicalLoadingStep asString +] + +{ #category : #hooks } +MDLNestedList >> states [ + self flag: #BECAREFUL. "I am absolutly not sure we want to do this. I let it to try but it might be removed." + ^ Array with: self +] + +{ #category : #accessing } +MDLNestedList >> strategy [ + ^ strategy + ifNil: [ strategy := MDLNestedListItemRenderAnchorStrategy new ] +] + +{ #category : #accessing } +MDLNestedList >> strategy: anObject [ + strategy := anObject +] + +{ #category : #researchField } +MDLNestedList >> withResearchField [ + self displayResearchField: true +] diff --git a/src/Material-Design-Lite-Widgets/MDLNestedListItemRenderAbstractStrategy.class.st b/src/Material-Design-Lite-Widgets/MDLNestedListItemRenderAbstractStrategy.class.st index e5dcf5a9..7d7fb49b 100644 --- a/src/Material-Design-Lite-Widgets/MDLNestedListItemRenderAbstractStrategy.class.st +++ b/src/Material-Design-Lite-Widgets/MDLNestedListItemRenderAbstractStrategy.class.st @@ -1,221 +1,221 @@ -Class { - #name : #MDLNestedListItemRenderAbstractStrategy, - #superclass : #MDLWidget, - #instVars : [ - 'isJsAction', - 'actionBlock', - 'helpBlock', - 'childrenBlock', - 'childrenSortBlock', - 'entryCustomizationHook', - 'format', - 'iconBlock', - 'rightIconBlock' - ], - #category : #'Material-Design-Lite-Widgets-List' -} - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> actionBlock [ - ^ actionBlock -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> actionBlock: anObject [ - actionBlock := anObject -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> childrenBlock [ - ^ childrenBlock -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> childrenBlock: anObject [ - childrenBlock := anObject -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> childrenSortBlock [ - ^ childrenSortBlock -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> childrenSortBlock: anObject [ - childrenSortBlock := anObject -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> entryCustomizationHook [ - ^ entryCustomizationHook -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> entryCustomizationHook: anObject [ - entryCustomizationHook := anObject -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> format [ - ^ format -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> format: anObject [ - format := anObject -] - -{ #category : #testing } -MDLNestedListItemRenderAbstractStrategy >> hasCustomizationForEntry [ - ^ self entryCustomizationHook notNil -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> helpBlock [ - ^ helpBlock -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> helpBlock: anObject [ - helpBlock := anObject -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> iconBlock [ - ^ iconBlock -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> iconBlock: anObject [ - iconBlock := anObject -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> isJsAction [ - ^ isJsAction -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> isJsAction: anObject [ - isJsAction := anObject -] - -{ #category : #rendering } -MDLNestedListItemRenderAbstractStrategy >> renderHelpOf: anItem at: anId on: html [ - | helpText | - (self helpBlock isNil - or: [ self helpBlock argumentCount = 1 and: [ (helpText := self helpBlock value: anItem) isEmptyOrNil ] ]) - ifTrue: [ ^ self ]. - - html mdlTooltip - large; - for: anId; - with: - (self helpBlock argumentCount = 1 - ifTrue: [ helpText ] - ifFalse: [ self helpBlock mdlCull: anItem cull: html ]) -] - -{ #category : #rendering } -MDLNestedListItemRenderAbstractStrategy >> renderIcon: aBlock Of: anItem on: html [ - aBlock ifNil: [ ^ self ]. - - self - assert: (aBlock argumentCount between: 1 and: 2) - description: - 'The icon block should have 1 or 2 arguments only. The first argument should be the item to display. If this is the only parameter the block should return a WAComponent to render. The second optional parameter will be an html canvas if you want to render directly something without passing by a component.'. - - aBlock argumentCount = 1 - ifTrue: [ html render: (aBlock value: anItem) ] - ifFalse: [ aBlock value: anItem value: html ] -] - -{ #category : #rendering } -MDLNestedListItemRenderAbstractStrategy >> renderItem: aNode index: anIndex inDiv: div indentedBy: anInteger on: html [ - | htmlElement | - htmlElement := self getHtmlElementForNode: aNode inDiv: div index: anIndex indentedBy: anInteger on: html. - htmlElement - with: [ html span - class: #item; - id: html nextId; - with: ((self format value: aNode element) ifEmpty: [ $  ]). - self renderHelpOf: aNode element at: html lastId on: html ]. - aNode children - ifNotEmpty: [ html div - onClick: 'expandCollapse(this)'; - class: #icon ] -] - -{ #category : #rendering } -MDLNestedListItemRenderAbstractStrategy >> renderItemContentOf: aNode index: anIndex indentedBy: anInteger on: html [ - | div | - div := html div class: #itemContener. - self hasCustomizationForEntry - ifTrue: [ self entryCustomizationHook mdlCull: div cull: aNode element ]. - div - attributeAt: 'draggable' put: 'true'; - attributeAt: 'onDragOver' - put: 'if("' , anIndex asString , '" != event.dataTransfer.getData("sourceIndex")) {event.preventDefault();}'; - attributeAt: 'ondrop' put: 'dropListItem(event, "' , anIndex asString , '");'; - attributeAt: 'ondragstart' put: 'dragListItem(event,"' , anIndex asString , '")'; - style: 'padding-left: ' , (15 * anInteger) asString , 'px;'; - class: #isSelected if: aNode selectedElement; - with: [ - self renderIcon: self iconBlock Of: aNode element on: html. - self - renderItem: aNode - index: anIndex - inDiv: div - indentedBy: anInteger - on: html. - self renderIcon: self rightIconBlock Of: aNode element on: html ] -] - -{ #category : #rendering } -MDLNestedListItemRenderAbstractStrategy >> renderListTree: aTree index: index indentedBy: indentation on: html [ - html listItem - class: #expanded if: aTree selectedBranch; - class: #collapsed if: aTree selectedBranch not; - class: #hasChildren if: aTree children isNotEmpty; - attributeAt: #index put: index; - with: [ - self - renderItemContentOf: aTree - index: index - indentedBy: indentation - on: html. - aTree selectedBranch - ifTrue: [ - self - renderSublistOf: aTree children - parentIndex: index - indentedBy: indentation - on: html ] ] -] - -{ #category : #rendering } -MDLNestedListItemRenderAbstractStrategy >> renderSublistOf: children parentIndex: parentIndex indentedBy: anInteger on: html [ - | sortedChildren | - children ifEmpty: [ ^ self ]. - - sortedChildren := self childrenSortBlock ifNil: [ children ] ifNotNil: [ :sortBlock | children sorted: [ :node1 :node2 | sortBlock value: node1 element value: node2 element ] ]. - html - unorderedList: [ - sortedChildren - doWithIndex: [ :child :index | - self - renderListTree: child - index: parentIndex asString, ':', index asString - indentedBy: anInteger + 1 - on: html ] ] -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> rightIconBlock [ - ^ rightIconBlock -] - -{ #category : #accessing } -MDLNestedListItemRenderAbstractStrategy >> rightIconBlock: anObject [ - rightIconBlock := anObject -] +Class { + #name : #MDLNestedListItemRenderAbstractStrategy, + #superclass : #MDLWidget, + #instVars : [ + 'isJsAction', + 'actionBlock', + 'helpBlock', + 'childrenBlock', + 'childrenSortBlock', + 'entryCustomizationHook', + 'format', + 'iconBlock', + 'rightIconBlock' + ], + #category : #'Material-Design-Lite-Widgets-List' +} + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> actionBlock [ + ^ actionBlock +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> actionBlock: anObject [ + actionBlock := anObject +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> childrenBlock [ + ^ childrenBlock +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> childrenBlock: anObject [ + childrenBlock := anObject +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> childrenSortBlock [ + ^ childrenSortBlock +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> childrenSortBlock: anObject [ + childrenSortBlock := anObject +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> entryCustomizationHook [ + ^ entryCustomizationHook +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> entryCustomizationHook: anObject [ + entryCustomizationHook := anObject +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> format [ + ^ format +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> format: anObject [ + format := anObject +] + +{ #category : #testing } +MDLNestedListItemRenderAbstractStrategy >> hasCustomizationForEntry [ + ^ self entryCustomizationHook notNil +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> helpBlock [ + ^ helpBlock +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> helpBlock: anObject [ + helpBlock := anObject +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> iconBlock [ + ^ iconBlock +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> iconBlock: anObject [ + iconBlock := anObject +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> isJsAction [ + ^ isJsAction +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> isJsAction: anObject [ + isJsAction := anObject +] + +{ #category : #rendering } +MDLNestedListItemRenderAbstractStrategy >> renderHelpOf: anItem at: anId on: html [ + | helpText | + (self helpBlock isNil + or: [ self helpBlock argumentCount = 1 and: [ (helpText := self helpBlock value: anItem) isEmptyOrNil ] ]) + ifTrue: [ ^ self ]. + + html mdlTooltip + large; + for: anId; + with: + (self helpBlock argumentCount = 1 + ifTrue: [ helpText ] + ifFalse: [ self helpBlock mdlCull: anItem cull: html ]) +] + +{ #category : #rendering } +MDLNestedListItemRenderAbstractStrategy >> renderIcon: aBlock Of: anItem on: html [ + aBlock ifNil: [ ^ self ]. + + self + assert: (aBlock argumentCount between: 1 and: 2) + description: + 'The icon block should have 1 or 2 arguments only. The first argument should be the item to display. If this is the only parameter the block should return a WAComponent to render. The second optional parameter will be an html canvas if you want to render directly something without passing by a component.'. + + aBlock argumentCount = 1 + ifTrue: [ html render: (aBlock value: anItem) ] + ifFalse: [ aBlock value: anItem value: html ] +] + +{ #category : #rendering } +MDLNestedListItemRenderAbstractStrategy >> renderItem: aNode index: anIndex inDiv: div indentedBy: anInteger on: html [ + | htmlElement | + htmlElement := self getHtmlElementForNode: aNode inDiv: div index: anIndex indentedBy: anInteger on: html. + htmlElement + with: [ html span + class: #item; + id: html nextId; + with: ((self format value: aNode element) ifEmpty: [ $  ]). + self renderHelpOf: aNode element at: html lastId on: html ]. + aNode children + ifNotEmpty: [ html div + onClick: 'expandCollapse(this)'; + class: #icon ] +] + +{ #category : #rendering } +MDLNestedListItemRenderAbstractStrategy >> renderItemContentOf: aNode index: anIndex indentedBy: anInteger on: html [ + | div | + div := html div class: #itemContener. + self hasCustomizationForEntry + ifTrue: [ self entryCustomizationHook mdlCull: div cull: aNode element ]. + div + attributeAt: 'draggable' put: 'true'; + attributeAt: 'onDragOver' + put: 'if("' , anIndex asString , '" != event.dataTransfer.getData("sourceIndex")) {event.preventDefault();}'; + attributeAt: 'ondrop' put: 'dropListItem(event, "' , anIndex asString , '");'; + attributeAt: 'ondragstart' put: 'dragListItem(event,"' , anIndex asString , '")'; + style: 'padding-left: ' , (15 * anInteger) asString , 'px;'; + class: #isSelected if: aNode selectedElement; + with: [ + self renderIcon: self iconBlock Of: aNode element on: html. + self + renderItem: aNode + index: anIndex + inDiv: div + indentedBy: anInteger + on: html. + self renderIcon: self rightIconBlock Of: aNode element on: html ] +] + +{ #category : #rendering } +MDLNestedListItemRenderAbstractStrategy >> renderListTree: aTree index: index indentedBy: indentation on: html [ + html listItem + class: #expanded if: aTree selectedBranch; + class: #collapsed if: aTree selectedBranch not; + class: #hasChildren if: aTree children isNotEmpty; + attributeAt: #index put: index; + with: [ + self + renderItemContentOf: aTree + index: index + indentedBy: indentation + on: html. + aTree selectedBranch + ifTrue: [ + self + renderSublistOf: aTree children + parentIndex: index + indentedBy: indentation + on: html ] ] +] + +{ #category : #rendering } +MDLNestedListItemRenderAbstractStrategy >> renderSublistOf: children parentIndex: parentIndex indentedBy: anInteger on: html [ + | sortedChildren | + children ifEmpty: [ ^ self ]. + + sortedChildren := self childrenSortBlock ifNil: [ children ] ifNotNil: [ :sortBlock | children sorted: [ :node1 :node2 | sortBlock value: node1 element value: node2 element ] ]. + html + unorderedList: [ + sortedChildren + doWithIndex: [ :child :index | + self + renderListTree: child + index: parentIndex asString, ':', index asString + indentedBy: anInteger + 1 + on: html ] ] +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> rightIconBlock [ + ^ rightIconBlock +] + +{ #category : #accessing } +MDLNestedListItemRenderAbstractStrategy >> rightIconBlock: anObject [ + rightIconBlock := anObject +] diff --git a/src/Material-Design-Lite-Widgets/MDLNestedListItemRenderAjaxStrategy.class.st b/src/Material-Design-Lite-Widgets/MDLNestedListItemRenderAjaxStrategy.class.st index 74a8fcd4..1ae9b1a3 100644 --- a/src/Material-Design-Lite-Widgets/MDLNestedListItemRenderAjaxStrategy.class.st +++ b/src/Material-Design-Lite-Widgets/MDLNestedListItemRenderAjaxStrategy.class.st @@ -1,22 +1,22 @@ -Class { - #name : #MDLNestedListItemRenderAjaxStrategy, - #superclass : #MDLNestedListItemRenderAbstractStrategy, - #category : #'Material-Design-Lite-Widgets-List' -} - -{ #category : #'as yet unclassified' } -MDLNestedListItemRenderAjaxStrategy >> asAjaxStrategy [ - ^ self -] - -{ #category : #'as yet unclassified' } -MDLNestedListItemRenderAjaxStrategy >> getHtmlElementForNode: aNode inDiv: div index: anIndex indentedBy: anInteger on: html [ - ^ html div - onClick: (self actionBlock cull: aNode element). -] - -{ #category : #'as yet unclassified' } -MDLNestedListItemRenderAjaxStrategy >> initialize [ - super initialize. - self isJsAction: true -] +Class { + #name : #MDLNestedListItemRenderAjaxStrategy, + #superclass : #MDLNestedListItemRenderAbstractStrategy, + #category : #'Material-Design-Lite-Widgets-List' +} + +{ #category : #'as yet unclassified' } +MDLNestedListItemRenderAjaxStrategy >> asAjaxStrategy [ + ^ self +] + +{ #category : #'as yet unclassified' } +MDLNestedListItemRenderAjaxStrategy >> getHtmlElementForNode: aNode inDiv: div index: anIndex indentedBy: anInteger on: html [ + ^ html div + onClick: (self actionBlock cull: aNode element). +] + +{ #category : #'as yet unclassified' } +MDLNestedListItemRenderAjaxStrategy >> initialize [ + super initialize. + self isJsAction: true +] diff --git a/src/Material-Design-Lite-Widgets/MDLNestedListItemRenderAnchorStrategy.class.st b/src/Material-Design-Lite-Widgets/MDLNestedListItemRenderAnchorStrategy.class.st index 8e42c29b..691f1ad5 100644 --- a/src/Material-Design-Lite-Widgets/MDLNestedListItemRenderAnchorStrategy.class.st +++ b/src/Material-Design-Lite-Widgets/MDLNestedListItemRenderAnchorStrategy.class.st @@ -1,56 +1,56 @@ -Class { - #name : #MDLNestedListItemRenderAnchorStrategy, - #superclass : #MDLNestedListItemRenderAbstractStrategy, - #category : #'Material-Design-Lite-Widgets-List' -} - -{ #category : #'as yet unclassified' } -MDLNestedListItemRenderAnchorStrategy >> asAjaxStrategy [ - ^ MDLNestedListItemRenderAjaxStrategy new - isJsAction: isJsAction; - actionBlock: actionBlock; - helpBlock: helpBlock; - childrenBlock: childrenBlock; - childrenSortBlock: childrenSortBlock; - entryCustomizationHook: entryCustomizationHook; - format: format; - iconBlock: iconBlock; - rightIconBlock: rightIconBlock; - yourself -] - -{ #category : #'as yet unclassified' } -MDLNestedListItemRenderAnchorStrategy >> getHtmlElementForNode: aNode inDiv: div index: anIndex indentedBy: anInteger on: html [ - | anchor | - anchor := html anchor. - self actionBlock - ifNotNil: [ self isJsAction - ifTrue: [ anchor - onClick: - (self - overwriteOnCompleteForNode: aNode - inDiv: div - index: anIndex - indentedBy: anInteger - on: html) ] - ifFalse: [ anchor callback: [ self actionBlock value: aNode element ] ] ]. - ^ anchor -] - -{ #category : #rendering } -MDLNestedListItemRenderAnchorStrategy >> overwriteOnCompleteForNode: aNode inDiv: div index: anIndex indentedBy: anInteger on: html [ - | onClickValue selfOnComplete finalOnComplete | - onClickValue := self actionBlock value: aNode element. - selfOnComplete := (html jQuery id: div) load - html: [ :ajaxHtml | - self - renderItemContentOf: aNode - index: anIndex - indentedBy: anInteger - on: ajaxHtml ]. - [ finalOnComplete := selfOnComplete onComplete: (onClickValue options - at: 'complete' )] - on: GRError do: [ finalOnComplete := selfOnComplete ]. - onClickValue onComplete: finalOnComplete. - ^ onClickValue -] +Class { + #name : #MDLNestedListItemRenderAnchorStrategy, + #superclass : #MDLNestedListItemRenderAbstractStrategy, + #category : #'Material-Design-Lite-Widgets-List' +} + +{ #category : #'as yet unclassified' } +MDLNestedListItemRenderAnchorStrategy >> asAjaxStrategy [ + ^ MDLNestedListItemRenderAjaxStrategy new + isJsAction: isJsAction; + actionBlock: actionBlock; + helpBlock: helpBlock; + childrenBlock: childrenBlock; + childrenSortBlock: childrenSortBlock; + entryCustomizationHook: entryCustomizationHook; + format: format; + iconBlock: iconBlock; + rightIconBlock: rightIconBlock; + yourself +] + +{ #category : #'as yet unclassified' } +MDLNestedListItemRenderAnchorStrategy >> getHtmlElementForNode: aNode inDiv: div index: anIndex indentedBy: anInteger on: html [ + | anchor | + anchor := html anchor. + self actionBlock + ifNotNil: [ self isJsAction + ifTrue: [ anchor + onClick: + (self + overwriteOnCompleteForNode: aNode + inDiv: div + index: anIndex + indentedBy: anInteger + on: html) ] + ifFalse: [ anchor callback: [ self actionBlock value: aNode element ] ] ]. + ^ anchor +] + +{ #category : #rendering } +MDLNestedListItemRenderAnchorStrategy >> overwriteOnCompleteForNode: aNode inDiv: div index: anIndex indentedBy: anInteger on: html [ + | onClickValue selfOnComplete finalOnComplete | + onClickValue := self actionBlock value: aNode element. + selfOnComplete := (html jQuery id: div) load + html: [ :ajaxHtml | + self + renderItemContentOf: aNode + index: anIndex + indentedBy: anInteger + on: ajaxHtml ]. + [ finalOnComplete := selfOnComplete onComplete: (onClickValue options + at: 'complete' )] + on: GRError do: [ finalOnComplete := selfOnComplete ]. + onClickValue onComplete: finalOnComplete. + ^ onClickValue +] diff --git a/src/Material-Design-Lite-Widgets/MDLNestedListTreeNode.class.st b/src/Material-Design-Lite-Widgets/MDLNestedListTreeNode.class.st index 2442bb92..b291a0aa 100644 --- a/src/Material-Design-Lite-Widgets/MDLNestedListTreeNode.class.st +++ b/src/Material-Design-Lite-Widgets/MDLNestedListTreeNode.class.st @@ -1,67 +1,67 @@ -" -I AM NOT AN USABLE COMPONENT, I AM A TOOL CLASS - -I am an object used when computing children for an element. It regroups the element, its children and a flag if it is the selected branch. -" -Class { - #name : #MDLNestedListTreeNode, - #superclass : #Object, - #instVars : [ - 'list', - 'element', - 'children', - 'selectedBranch' - ], - #category : #'Material-Design-Lite-Widgets-List' -} - -{ #category : #'instance creation' } -MDLNestedListTreeNode class >> list: aNestedList element: anElement [ - ^ self new - list: aNestedList; - element: anElement; - yourself -] - -{ #category : #accessing } -MDLNestedListTreeNode >> children [ - ^ children ifNil: [ children := (self list childrenBlock value: self element) collect: [ :aChild | self list obtainTreeFor: aChild ] ] -] - -{ #category : #accessing } -MDLNestedListTreeNode >> element [ - ^ element -] - -{ #category : #accessing } -MDLNestedListTreeNode >> element: anObject [ - element := anObject -] - -{ #category : #accessing } -MDLNestedListTreeNode >> list [ - ^ list -] - -{ #category : #accessing } -MDLNestedListTreeNode >> list: anObject [ - list := anObject -] - -{ #category : #printing } -MDLNestedListTreeNode >> printOn: aStream [ - super printOn: aStream. - aStream nextPut: $[. - element printOn: aStream. - aStream nextPut: $] -] - -{ #category : #accessing } -MDLNestedListTreeNode >> selectedBranch [ - ^ selectedBranch ifNil: [ selectedBranch := self children anySatisfy: [ :aChild | aChild selectedElement or: [ aChild selectedBranch ] ] ] -] - -{ #category : #accessing } -MDLNestedListTreeNode >> selectedElement [ - ^ element = self list selectedEntity -] +" +I AM NOT AN USABLE COMPONENT, I AM A TOOL CLASS + +I am an object used when computing children for an element. It regroups the element, its children and a flag if it is the selected branch. +" +Class { + #name : #MDLNestedListTreeNode, + #superclass : #Object, + #instVars : [ + 'list', + 'element', + 'children', + 'selectedBranch' + ], + #category : #'Material-Design-Lite-Widgets-List' +} + +{ #category : #'instance creation' } +MDLNestedListTreeNode class >> list: aNestedList element: anElement [ + ^ self new + list: aNestedList; + element: anElement; + yourself +] + +{ #category : #accessing } +MDLNestedListTreeNode >> children [ + ^ children ifNil: [ children := (self list childrenBlock value: self element) collect: [ :aChild | self list obtainTreeFor: aChild ] ] +] + +{ #category : #accessing } +MDLNestedListTreeNode >> element [ + ^ element +] + +{ #category : #accessing } +MDLNestedListTreeNode >> element: anObject [ + element := anObject +] + +{ #category : #accessing } +MDLNestedListTreeNode >> list [ + ^ list +] + +{ #category : #accessing } +MDLNestedListTreeNode >> list: anObject [ + list := anObject +] + +{ #category : #printing } +MDLNestedListTreeNode >> printOn: aStream [ + super printOn: aStream. + aStream nextPut: $[. + element printOn: aStream. + aStream nextPut: $] +] + +{ #category : #accessing } +MDLNestedListTreeNode >> selectedBranch [ + ^ selectedBranch ifNil: [ selectedBranch := self children anySatisfy: [ :aChild | aChild selectedElement or: [ aChild selectedBranch ] ] ] +] + +{ #category : #accessing } +MDLNestedListTreeNode >> selectedElement [ + ^ element = self list selectedEntity +] diff --git a/src/Material-Design-Lite-Widgets/MDLNewPasswordWidget.class.st b/src/Material-Design-Lite-Widgets/MDLNewPasswordWidget.class.st index fdd85568..e6dbb486 100644 --- a/src/Material-Design-Lite-Widgets/MDLNewPasswordWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLNewPasswordWidget.class.st @@ -1,150 +1,150 @@ -" -I am a widget for password change -" -Class { - #name : #MDLNewPasswordWidget, - #superclass : #MDLHighLevelWidget, - #instVars : [ - 'currentPassword', - 'newPassword', - 'badPasswordBlock', - 'oldPasswordLabel', - 'newPasswordLabel', - 'onSuccessBlock', - 'confirmPasswordLabel', - 'notMatchingPasswordsBlock', - 'rightOldPassword', - 'pattern', - 'errorMessage' - ], - #category : 'Material-Design-Lite-Widgets' -} - -{ #category : #accessing } -MDLNewPasswordWidget >> badPasswordBlock [ - ^ badPasswordBlock ifNil: [ self error: 'Bad password' ] -] - -{ #category : #accessing } -MDLNewPasswordWidget >> badPasswordBlock: anObject [ - badPasswordBlock := anObject -] - -{ #category : #accessing } -MDLNewPasswordWidget >> confirmPasswordLabel [ - ^ confirmPasswordLabel ifNil: [ newPasswordLabel := 'Confirm password' ] -] - -{ #category : #accessing } -MDLNewPasswordWidget >> confirmPasswordLabel: anObject [ - confirmPasswordLabel := anObject -] - -{ #category : #accessing } -MDLNewPasswordWidget >> currentPassword [ - ^ currentPassword -] - -{ #category : #accessing } -MDLNewPasswordWidget >> currentPassword: anObject [ - currentPassword := anObject -] - -{ #category : #initialization } -MDLNewPasswordWidget >> initialize [ - super initialize. - rightOldPassword := false. - pattern := ''. - errorMessage := '' -] - -{ #category : #accessing } -MDLNewPasswordWidget >> newPassword [ - ^ newPassword -] - -{ #category : #accessing } -MDLNewPasswordWidget >> newPassword: anObject [ - newPassword := anObject -] - -{ #category : #accessing } -MDLNewPasswordWidget >> newPasswordLabel [ - ^ newPasswordLabel ifNil: [ newPasswordLabel := 'New password' ] -] - -{ #category : #accessing } -MDLNewPasswordWidget >> newPasswordLabel: anObject [ - ^ newPasswordLabel := anObject -] - -{ #category : #accessing } -MDLNewPasswordWidget >> notMatchingPasswordsBlock [ - ^ notMatchingPasswordsBlock ifNil: [ self error: 'Passwords don''t match' ] -] - -{ #category : #accessing } -MDLNewPasswordWidget >> notMatchingPasswordsBlock: anObject [ - notMatchingPasswordsBlock := anObject -] - -{ #category : #accessing } -MDLNewPasswordWidget >> oldPasswordLabel [ - ^ oldPasswordLabel ifNil: [ oldPasswordLabel := 'Current password' ] -] - -{ #category : #accessing } -MDLNewPasswordWidget >> oldPasswordLabel: anObject [ - ^ oldPasswordLabel := anObject -] - -{ #category : #accessing } -MDLNewPasswordWidget >> onSuccessBlock [ - ^ onSuccessBlock ifNil: [ ^ [ ] ] -] - -{ #category : #accessing } -MDLNewPasswordWidget >> onSuccessBlock: anObject [ - onSuccessBlock := anObject -] - -{ #category : #options } -MDLNewPasswordWidget >> pattern: aPattern errorMessage: aString [ - pattern := aPattern. - errorMessage := aString -] - -{ #category : #rendering } -MDLNewPasswordWidget >> renderContentOn: html [ - html - render: - (MDLTextFieldWidget new - beFloatingLabel; - type: 'password'; - callback: [ :aString | - rightOldPassword := (MD5 hashMessage: aString) = currentPassword. - rightOldPassword - ifFalse: self badPasswordBlock ]; - label: self oldPasswordLabel; - yourself). - html - render: - (MDLTextFieldWidget new - beFloatingLabel; - type: 'password'; - pattern: pattern errorMessage: errorMessage; - on: #newPassword of: self; - label: self newPasswordLabel; - yourself). - html - render: - (MDLTextFieldWidget new - beFloatingLabel; - type: 'password'; - label: self confirmPasswordLabel; - callback: [ :aString | - aString = newPassword - ifFalse: self notMatchingPasswordsBlock - ifTrue: [ rightOldPassword - ifTrue: [ self onSuccessBlock value: aString ] ] ]) -] +" +I am a widget for password change +" +Class { + #name : #MDLNewPasswordWidget, + #superclass : #MDLHighLevelWidget, + #instVars : [ + 'currentPassword', + 'newPassword', + 'badPasswordBlock', + 'oldPasswordLabel', + 'newPasswordLabel', + 'onSuccessBlock', + 'confirmPasswordLabel', + 'notMatchingPasswordsBlock', + 'rightOldPassword', + 'pattern', + 'errorMessage' + ], + #category : 'Material-Design-Lite-Widgets' +} + +{ #category : #accessing } +MDLNewPasswordWidget >> badPasswordBlock [ + ^ badPasswordBlock ifNil: [ self error: 'Bad password' ] +] + +{ #category : #accessing } +MDLNewPasswordWidget >> badPasswordBlock: anObject [ + badPasswordBlock := anObject +] + +{ #category : #accessing } +MDLNewPasswordWidget >> confirmPasswordLabel [ + ^ confirmPasswordLabel ifNil: [ newPasswordLabel := 'Confirm password' ] +] + +{ #category : #accessing } +MDLNewPasswordWidget >> confirmPasswordLabel: anObject [ + confirmPasswordLabel := anObject +] + +{ #category : #accessing } +MDLNewPasswordWidget >> currentPassword [ + ^ currentPassword +] + +{ #category : #accessing } +MDLNewPasswordWidget >> currentPassword: anObject [ + currentPassword := anObject +] + +{ #category : #initialization } +MDLNewPasswordWidget >> initialize [ + super initialize. + rightOldPassword := false. + pattern := ''. + errorMessage := '' +] + +{ #category : #accessing } +MDLNewPasswordWidget >> newPassword [ + ^ newPassword +] + +{ #category : #accessing } +MDLNewPasswordWidget >> newPassword: anObject [ + newPassword := anObject +] + +{ #category : #accessing } +MDLNewPasswordWidget >> newPasswordLabel [ + ^ newPasswordLabel ifNil: [ newPasswordLabel := 'New password' ] +] + +{ #category : #accessing } +MDLNewPasswordWidget >> newPasswordLabel: anObject [ + ^ newPasswordLabel := anObject +] + +{ #category : #accessing } +MDLNewPasswordWidget >> notMatchingPasswordsBlock [ + ^ notMatchingPasswordsBlock ifNil: [ self error: 'Passwords don''t match' ] +] + +{ #category : #accessing } +MDLNewPasswordWidget >> notMatchingPasswordsBlock: anObject [ + notMatchingPasswordsBlock := anObject +] + +{ #category : #accessing } +MDLNewPasswordWidget >> oldPasswordLabel [ + ^ oldPasswordLabel ifNil: [ oldPasswordLabel := 'Current password' ] +] + +{ #category : #accessing } +MDLNewPasswordWidget >> oldPasswordLabel: anObject [ + ^ oldPasswordLabel := anObject +] + +{ #category : #accessing } +MDLNewPasswordWidget >> onSuccessBlock [ + ^ onSuccessBlock ifNil: [ ^ [ ] ] +] + +{ #category : #accessing } +MDLNewPasswordWidget >> onSuccessBlock: anObject [ + onSuccessBlock := anObject +] + +{ #category : #options } +MDLNewPasswordWidget >> pattern: aPattern errorMessage: aString [ + pattern := aPattern. + errorMessage := aString +] + +{ #category : #rendering } +MDLNewPasswordWidget >> renderContentOn: html [ + html + render: + (MDLTextFieldWidget new + beFloatingLabel; + type: 'password'; + callback: [ :aString | + rightOldPassword := (MD5 hashMessage: aString) = currentPassword. + rightOldPassword + ifFalse: self badPasswordBlock ]; + label: self oldPasswordLabel; + yourself). + html + render: + (MDLTextFieldWidget new + beFloatingLabel; + type: 'password'; + pattern: pattern errorMessage: errorMessage; + on: #newPassword of: self; + label: self newPasswordLabel; + yourself). + html + render: + (MDLTextFieldWidget new + beFloatingLabel; + type: 'password'; + label: self confirmPasswordLabel; + callback: [ :aString | + aString = newPassword + ifFalse: self notMatchingPasswordsBlock + ifTrue: [ rightOldPassword + ifTrue: [ self onSuccessBlock value: aString ] ] ]) +] diff --git a/src/Material-Design-Lite-Widgets/MDLNilLayoutSection.class.st b/src/Material-Design-Lite-Widgets/MDLNilLayoutSection.class.st index 40cddedb..dae63fe9 100644 --- a/src/Material-Design-Lite-Widgets/MDLNilLayoutSection.class.st +++ b/src/Material-Design-Lite-Widgets/MDLNilLayoutSection.class.st @@ -1,10 +1,10 @@ -Class { - #name : #MDLNilLayoutSection, - #superclass : #MDLAbstractLayoutSection, - #category : 'Material-Design-Lite-Widgets-Header' -} - -{ #category : #'as yet unclassified' } -MDLNilLayoutSection >> renderContentOn: html [ - "do nothing" -] +Class { + #name : #MDLNilLayoutSection, + #superclass : #MDLAbstractLayoutSection, + #category : 'Material-Design-Lite-Widgets-Header' +} + +{ #category : #'as yet unclassified' } +MDLNilLayoutSection >> renderContentOn: html [ + "do nothing" +] diff --git a/src/Material-Design-Lite-Widgets/MDLNumericColumnDescription.class.st b/src/Material-Design-Lite-Widgets/MDLNumericColumnDescription.class.st index 31d45bac..d2ccaa27 100644 --- a/src/Material-Design-Lite-Widgets/MDLNumericColumnDescription.class.st +++ b/src/Material-Design-Lite-Widgets/MDLNumericColumnDescription.class.st @@ -1,25 +1,25 @@ -" -I model a numeric column. - -My values are of kind numeric. Because of that, I align the title of the column on the right side. -" -Class { - #name : #MDLNumericColumnDescription, - #superclass : #MDLTableColumnDescription, - #category : #'Material-Design-Lite-Widgets-Table' -} - -{ #category : #rendering } -MDLNumericColumnDescription >> render: row on: html [ - html mdlTableCell - id: (self generateIdUsing: html); - class: 'mdl-table-widget__cell--numeric'; - with: (self evaluation value: row) -] - -{ #category : #rendering } -MDLNumericColumnDescription >> renderHeadingOn: html [ - (super renderHeadingOn: html) - class: 'mdl-table-widget__cell--numeric'; - with: self title. -] +" +I model a numeric column. + +My values are of kind numeric. Because of that, I align the title of the column on the right side. +" +Class { + #name : #MDLNumericColumnDescription, + #superclass : #MDLTableColumnDescription, + #category : #'Material-Design-Lite-Widgets-Table' +} + +{ #category : #rendering } +MDLNumericColumnDescription >> render: row on: html [ + html mdlTableCell + id: (self generateIdUsing: html); + class: 'mdl-table-widget__cell--numeric'; + with: (self evaluation value: row) +] + +{ #category : #rendering } +MDLNumericColumnDescription >> renderHeadingOn: html [ + (super renderHeadingOn: html) + class: 'mdl-table-widget__cell--numeric'; + with: self title. +] diff --git a/src/Material-Design-Lite-Widgets/MDLPoll.class.st b/src/Material-Design-Lite-Widgets/MDLPoll.class.st index eca00582..ffed4df8 100644 --- a/src/Material-Design-Lite-Widgets/MDLPoll.class.st +++ b/src/Material-Design-Lite-Widgets/MDLPoll.class.st @@ -1,61 +1,61 @@ -" -I am the model for MDLPollWidget. - -I just store the number of positive and negative count. -" -Class { - #name : #MDLPoll, - #superclass : #GRObject, - #instVars : [ - 'positiveCount', - 'negativeCount' - ], - #category : #'Material-Design-Lite-Widgets-Poll' -} - -{ #category : #accessing } -MDLPoll >> decreaseNegativeCount [ - negativeCount := negativeCount - 1 -] - -{ #category : #accessing } -MDLPoll >> decreasePositiveCount [ - positiveCount := positiveCount - 1 -] - -{ #category : #accessing } -MDLPoll >> increaseNegativeCount [ - negativeCount := negativeCount + 1 -] - -{ #category : #accessing } -MDLPoll >> increasePositiveCount [ - positiveCount := positiveCount + 1 -] - -{ #category : #initialization } -MDLPoll >> initialize [ - super initialize. - positiveCount := 0. - negativeCount := 0 -] - -{ #category : #accessing } -MDLPoll >> negativeCount [ - ^ negativeCount -] - -{ #category : #accessing } -MDLPoll >> negativeCount: anObject [ - negativeCount := anObject -] - -{ #category : #accessing } -MDLPoll >> positiveCount [ - ^ positiveCount -] - -{ #category : #accessing } -MDLPoll >> positiveCount: anObject [ - positiveCount := anObject -] +" +I am the model for MDLPollWidget. + +I just store the number of positive and negative count. +" +Class { + #name : #MDLPoll, + #superclass : #GRObject, + #instVars : [ + 'positiveCount', + 'negativeCount' + ], + #category : #'Material-Design-Lite-Widgets-Poll' +} + +{ #category : #accessing } +MDLPoll >> decreaseNegativeCount [ + negativeCount := negativeCount - 1 +] + +{ #category : #accessing } +MDLPoll >> decreasePositiveCount [ + positiveCount := positiveCount - 1 +] + +{ #category : #accessing } +MDLPoll >> increaseNegativeCount [ + negativeCount := negativeCount + 1 +] + +{ #category : #accessing } +MDLPoll >> increasePositiveCount [ + positiveCount := positiveCount + 1 +] + +{ #category : #initialization } +MDLPoll >> initialize [ + super initialize. + positiveCount := 0. + negativeCount := 0 +] + +{ #category : #accessing } +MDLPoll >> negativeCount [ + ^ negativeCount +] + +{ #category : #accessing } +MDLPoll >> negativeCount: anObject [ + negativeCount := anObject +] + +{ #category : #accessing } +MDLPoll >> positiveCount [ + ^ positiveCount +] + +{ #category : #accessing } +MDLPoll >> positiveCount: anObject [ + positiveCount := anObject +] diff --git a/src/Material-Design-Lite-Widgets/MDLPollWidget.class.st b/src/Material-Design-Lite-Widgets/MDLPollWidget.class.st index b87132f1..65a8ee43 100644 --- a/src/Material-Design-Lite-Widgets/MDLPollWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLPollWidget.class.st @@ -1,98 +1,98 @@ -" -I represent a widget for polling with thumbs. - -For you project, you must subclass me and override #negativePollBlock and #positivePollBlock -" -Class { - #name : #MDLPollWidget, - #superclass : #MDLHighLevelWidget, - #instVars : [ - 'model' - ], - #category : #'Material-Design-Lite-Widgets-Poll' -} - -{ #category : #'instance creation' } -MDLPollWidget class >> newWithPoll: aMDLPoll [ - ^ self new poll: aMDLPoll -] - -{ #category : #adding } -MDLPollWidget >> addNegativeVote [ - model increaseNegativeCount -] - -{ #category : #adding } -MDLPollWidget >> addPositiveVote [ - model increasePositiveCount -] - -{ #category : #initialization } -MDLPollWidget >> initialize [ - super initialize. - self class: 'mdl-poll-widget'. - model := MDLPoll new -] - -{ #category : #javascript } -MDLPollWidget >> jsNegativeButtonClickedOn: html [ - ^ (html jQuery id: self id) load - html: [ :ajaxHtml | - self addNegativeVote. - self renderPollButtonsOn: ajaxHtml ] -] - -{ #category : #javascript } -MDLPollWidget >> jsPositiveButtonClickedOn: html [ - ^ (html jQuery id: self id) load - html: [ :ajaxHtml | - self addPositiveVote. - self renderPollButtonsOn: ajaxHtml ] -] - -{ #category : #accessing } -MDLPollWidget >> model [ - ^ model -] - -{ #category : #accessing } -MDLPollWidget >> poll: aPoll [ - model := aPoll -] - -{ #category : #rendering } -MDLPollWidget >> renderContentOn: html [ - self ensureId: html. - html div - id: self id; - with: [ self renderPollButtonsOn: html ] -] - -{ #category : #rendering } -MDLPollWidget >> renderNegativePollButtonOn: html [ - html mdlIconBadge - overlap; - dataBadge: model negativeCount greaseString; - with: [ html mdlButton - rippleEffect; - onClick: (self jsNegativeButtonClickedOn: html); - icon: 'thumb_down' ] -] - -{ #category : #rendering } -MDLPollWidget >> renderPollButtonsOn: html [ - self renderPositivePollButtonOn: html. - self renderNegativePollButtonOn: html -] - -{ #category : #rendering } -MDLPollWidget >> renderPositivePollButtonOn: html [ - html mdlIconBadge - overlap; - dataBadge: model positiveCount greaseString; - with: [ html mdlButton - rippleEffect; - icon; - onClick: (self jsPositiveButtonClickedOn: html); - icon: 'thumb_up' ] -] +" +I represent a widget for polling with thumbs. + +For you project, you must subclass me and override #negativePollBlock and #positivePollBlock +" +Class { + #name : #MDLPollWidget, + #superclass : #MDLHighLevelWidget, + #instVars : [ + 'model' + ], + #category : #'Material-Design-Lite-Widgets-Poll' +} + +{ #category : #'instance creation' } +MDLPollWidget class >> newWithPoll: aMDLPoll [ + ^ self new poll: aMDLPoll +] + +{ #category : #adding } +MDLPollWidget >> addNegativeVote [ + model increaseNegativeCount +] + +{ #category : #adding } +MDLPollWidget >> addPositiveVote [ + model increasePositiveCount +] + +{ #category : #initialization } +MDLPollWidget >> initialize [ + super initialize. + self class: 'mdl-poll-widget'. + model := MDLPoll new +] + +{ #category : #javascript } +MDLPollWidget >> jsNegativeButtonClickedOn: html [ + ^ (html jQuery id: self id) load + html: [ :ajaxHtml | + self addNegativeVote. + self renderPollButtonsOn: ajaxHtml ] +] + +{ #category : #javascript } +MDLPollWidget >> jsPositiveButtonClickedOn: html [ + ^ (html jQuery id: self id) load + html: [ :ajaxHtml | + self addPositiveVote. + self renderPollButtonsOn: ajaxHtml ] +] + +{ #category : #accessing } +MDLPollWidget >> model [ + ^ model +] + +{ #category : #accessing } +MDLPollWidget >> poll: aPoll [ + model := aPoll +] + +{ #category : #rendering } +MDLPollWidget >> renderContentOn: html [ + self ensureId: html. + html div + id: self id; + with: [ self renderPollButtonsOn: html ] +] + +{ #category : #rendering } +MDLPollWidget >> renderNegativePollButtonOn: html [ + html mdlIconBadge + overlap; + dataBadge: model negativeCount greaseString; + with: [ html mdlButton + rippleEffect; + onClick: (self jsNegativeButtonClickedOn: html); + icon: 'thumb_down' ] +] + +{ #category : #rendering } +MDLPollWidget >> renderPollButtonsOn: html [ + self renderPositivePollButtonOn: html. + self renderNegativePollButtonOn: html +] + +{ #category : #rendering } +MDLPollWidget >> renderPositivePollButtonOn: html [ + html mdlIconBadge + overlap; + dataBadge: model positiveCount greaseString; + with: [ html mdlButton + rippleEffect; + icon; + onClick: (self jsPositiveButtonClickedOn: html); + icon: 'thumb_up' ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLProgressBarWidget.class.st b/src/Material-Design-Lite-Widgets/MDLProgressBarWidget.class.st index d9eda883..9dd7e3c8 100644 --- a/src/Material-Design-Lite-Widgets/MDLProgressBarWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLProgressBarWidget.class.st @@ -1,128 +1,128 @@ -" -Description --------------------- - -I am a widget that display a progress bar. This progress bar will be linked to a progression block. - -Public API and Key Messages --------------------- - -- #hidden To hide the progress bar at the page oppening - -Examples --------------------- - - - -Internal Representation and Key Implementation Points. --------------------- - - Instance Variables - hyde: If true, the progress bar will be hidden at the rendering - progressionBlock: This must have 0 parameter. It will be evaluated each time to know the progression of the bar. The returned value must be within 0 and 1. - refreshTime: The time between two evaluations of the progression block. A short time will refresh the bar more ofter but will require more work from the server - -" -Class { - #name : #MDLProgressBarWidget, - #superclass : #MDLWidget, - #instVars : [ - 'progressionBlock', - 'refreshTime', - 'hide' - ], - #category : #'Material-Design-Lite-Widgets-Loading' -} - -{ #category : #'instance creation' } -MDLProgressBarWidget class >> progression: aProgressionBlock [ - ^ self new - progressionBlock: aProgressionBlock; - yourself -] - -{ #category : #'instance creation' } -MDLProgressBarWidget class >> progression: aProgressionBlock every: aDuration [ - ^ self new - progressionBlock: aProgressionBlock; - refreshTime: aDuration; - yourself -] - -{ #category : #options } -MDLProgressBarWidget >> hidden [ - self hide: true -] - -{ #category : #accessing } -MDLProgressBarWidget >> hide [ - ^ hide -] - -{ #category : #accessing } -MDLProgressBarWidget >> hide: aBoolean [ - hide := aBoolean -] - -{ #category : #initialization } -MDLProgressBarWidget >> initialize [ - super initialize. - self refreshTime: 1 seconds. - self hide: false -] - -{ #category : #javascript } -MDLProgressBarWidget >> progressScript: html [ - self flag: #todo. "Cyril: I think we can clean a little this part. Maybe it should go partly in a javascript file" - ^ html document - addLoadScript: - ('var interval' , id , ' = setInterval(function(){') js - , - (html jQuery getJson - json: [ :json | - json - object: [ json key: #progress value: ((100 * self progressionBlock value) asInteger min: 100) ] ]; - onSuccess: - 'if(arguments[0].progress >= 100) window.clearInterval(interval' , id - , - '); - document.querySelector(''#' , id - , ''').MaterialProgress.setProgress(arguments[0].progress);') - , (';}, ' , self refreshTime asMilliSeconds asString , ');') js -] - -{ #category : #accessing } -MDLProgressBarWidget >> progressionBlock [ - ^ progressionBlock -] - -{ #category : #accessing } -MDLProgressBarWidget >> progressionBlock: aBlock [ - progressionBlock := aBlock -] - -{ #category : #accessing } -MDLProgressBarWidget >> refreshTime [ - ^ refreshTime -] - -{ #category : #accessing } -MDLProgressBarWidget >> refreshTime: aDuration [ - refreshTime := aDuration -] - -{ #category : #rendering } -MDLProgressBarWidget >> renderContentOn: html [ - self ensureId: html. - self flag: #todo. "This need some cleaning." - "The style should be in a css file" - html mdlProgressBar - style: 'margin: auto;' , (self hide ifTrue: [ 'display: none;' ] ifFalse: [ '' ]); - id: id. - self hide ifFalse: [ self progressScript: html ] -] - -{ #category : #javascript } -MDLProgressBarWidget >> showScript: html [ - ^ (html jQuery id: self id) show , (self progressScript: html) -] +" +Description +-------------------- + +I am a widget that display a progress bar. This progress bar will be linked to a progression block. + +Public API and Key Messages +-------------------- + +- #hidden To hide the progress bar at the page oppening + +Examples +-------------------- + + + +Internal Representation and Key Implementation Points. +-------------------- + + Instance Variables + hyde: If true, the progress bar will be hidden at the rendering + progressionBlock: This must have 0 parameter. It will be evaluated each time to know the progression of the bar. The returned value must be within 0 and 1. + refreshTime: The time between two evaluations of the progression block. A short time will refresh the bar more ofter but will require more work from the server + +" +Class { + #name : #MDLProgressBarWidget, + #superclass : #MDLWidget, + #instVars : [ + 'progressionBlock', + 'refreshTime', + 'hide' + ], + #category : #'Material-Design-Lite-Widgets-Loading' +} + +{ #category : #'instance creation' } +MDLProgressBarWidget class >> progression: aProgressionBlock [ + ^ self new + progressionBlock: aProgressionBlock; + yourself +] + +{ #category : #'instance creation' } +MDLProgressBarWidget class >> progression: aProgressionBlock every: aDuration [ + ^ self new + progressionBlock: aProgressionBlock; + refreshTime: aDuration; + yourself +] + +{ #category : #options } +MDLProgressBarWidget >> hidden [ + self hide: true +] + +{ #category : #accessing } +MDLProgressBarWidget >> hide [ + ^ hide +] + +{ #category : #accessing } +MDLProgressBarWidget >> hide: aBoolean [ + hide := aBoolean +] + +{ #category : #initialization } +MDLProgressBarWidget >> initialize [ + super initialize. + self refreshTime: 1 seconds. + self hide: false +] + +{ #category : #javascript } +MDLProgressBarWidget >> progressScript: html [ + self flag: #todo. "Cyril: I think we can clean a little this part. Maybe it should go partly in a javascript file" + ^ html document + addLoadScript: + ('var interval' , id , ' = setInterval(function(){') js + , + (html jQuery getJson + json: [ :json | + json + object: [ json key: #progress value: ((100 * self progressionBlock value) asInteger min: 100) ] ]; + onSuccess: + 'if(arguments[0].progress >= 100) window.clearInterval(interval' , id + , + '); + document.querySelector(''#' , id + , ''').MaterialProgress.setProgress(arguments[0].progress);') + , (';}, ' , self refreshTime asMilliSeconds asString , ');') js +] + +{ #category : #accessing } +MDLProgressBarWidget >> progressionBlock [ + ^ progressionBlock +] + +{ #category : #accessing } +MDLProgressBarWidget >> progressionBlock: aBlock [ + progressionBlock := aBlock +] + +{ #category : #accessing } +MDLProgressBarWidget >> refreshTime [ + ^ refreshTime +] + +{ #category : #accessing } +MDLProgressBarWidget >> refreshTime: aDuration [ + refreshTime := aDuration +] + +{ #category : #rendering } +MDLProgressBarWidget >> renderContentOn: html [ + self ensureId: html. + self flag: #todo. "This need some cleaning." + "The style should be in a css file" + html mdlProgressBar + style: 'margin: auto;' , (self hide ifTrue: [ 'display: none;' ] ifFalse: [ '' ]); + id: id. + self hide ifFalse: [ self progressScript: html ] +] + +{ #category : #javascript } +MDLProgressBarWidget >> showScript: html [ + ^ (html jQuery id: self id) show , (self progressScript: html) +] diff --git a/src/Material-Design-Lite-Widgets/MDLPseudoRegexFilter.class.st b/src/Material-Design-Lite-Widgets/MDLPseudoRegexFilter.class.st index 47ff8265..d35b35b5 100644 --- a/src/Material-Design-Lite-Widgets/MDLPseudoRegexFilter.class.st +++ b/src/Material-Design-Lite-Widgets/MDLPseudoRegexFilter.class.st @@ -1,31 +1,31 @@ -" -I am a nested list filter keeping only elements whose name includes the pattern of the user. BUT! If the pattern contains a ""*"" or a ""#"", I uses a regex fiter. -" -Class { - #name : #MDLPseudoRegexFilter, - #superclass : #MDLAbstractFilter, - #category : 'Material-Design-Lite-Widgets-List' -} - -{ #category : #accessing } -MDLPseudoRegexFilter class >> adaptPattern: aPattern [ - ^ String - streamContents: [ :s | - (aPattern includes: $*) - ifFalse: [ s nextPutAll: '.*' ]. - s nextPutAll: ('.*' join: ($* split: aPattern)). - (aPattern includes: $*) - ifFalse: [ s nextPutAll: '.*' ] ] -] - -{ #category : #accessing } -MDLPseudoRegexFilter class >> formatedElement: aString matches: aRegex [ - ^ aRegex matches: aString -] - -{ #category : #accessing } -MDLPseudoRegexFilter class >> selectMatchingFrom: aCollection format: aFormatBlock with: aPattern [ - | regex | - regex := (self adaptPattern: aPattern) asRegexIgnoringCase. - ^ aCollection select: [ :each | self formatedElement: (aFormatBlock value: each) matches: regex ] -] +" +I am a nested list filter keeping only elements whose name includes the pattern of the user. BUT! If the pattern contains a ""*"" or a ""#"", I uses a regex fiter. +" +Class { + #name : #MDLPseudoRegexFilter, + #superclass : #MDLAbstractFilter, + #category : 'Material-Design-Lite-Widgets-List' +} + +{ #category : #accessing } +MDLPseudoRegexFilter class >> adaptPattern: aPattern [ + ^ String + streamContents: [ :s | + (aPattern includes: $*) + ifFalse: [ s nextPutAll: '.*' ]. + s nextPutAll: ('.*' join: ($* split: aPattern)). + (aPattern includes: $*) + ifFalse: [ s nextPutAll: '.*' ] ] +] + +{ #category : #accessing } +MDLPseudoRegexFilter class >> formatedElement: aString matches: aRegex [ + ^ aRegex matches: aString +] + +{ #category : #accessing } +MDLPseudoRegexFilter class >> selectMatchingFrom: aCollection format: aFormatBlock with: aPattern [ + | regex | + regex := (self adaptPattern: aPattern) asRegexIgnoringCase. + ^ aCollection select: [ :each | self formatedElement: (aFormatBlock value: each) matches: regex ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLSelectWidget.class.st b/src/Material-Design-Lite-Widgets/MDLSelectWidget.class.st index 32736b13..0b1bebb5 100644 --- a/src/Material-Design-Lite-Widgets/MDLSelectWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLSelectWidget.class.st @@ -1,433 +1,433 @@ -" -I am a widget trying to reproduce the behavior of a select input of a form with a WDL compatible design. - -Description --------------------- - -I am a widget with a list of possibilities that can select the user. - -I MUST be used inside a form and I will execute a callback on the submit. - -I have a tricky implementation, for more informations check the implementations detail at the end of the comment. - -Public API and Key Messages --------------------- - -There is many constructors in my class side. - -- #defaultSorting Use this method to sort the labels using the #<= operator by default -- #beAutoSubmit Use this method if you want to form to submit when the user select a value. Do not forget to put your widget in a form. - -Examples -------------------- - - MDLSelectWidget new - possibilities: #(1 2 3 4 5 5); - labelBlock: [ :number | number = 5 ifTrue: [ '0' ] ifFalse: [ (number - 1) asString ] ]; - choosingText: 'Select Your Number'; - selectedObject: 3; - defaultSorting; - callback: [ :input | Transcript << input; cr ]; - description: 'description'; - beAutoSubmit; - yourself. - - - MDLSelectWidget - possibilities: #(1 2 3 4 5 5) - inputLabel: 'Select Your Number' - labelBlock: [ :number | number = 5 ifTrue: [ '0' ] ifFalse: [ (number - 1) asString ] ] - callback: [ :input | Transcript << input; cr ] - selectedObject: 3 - tooltip: 'description' - sortBlock: [ :a :b | a > b ] - -Internal Representation and Key Implementation Points. -------------------- - - Instance Variables - autoSubmit: If true, the form will be submit when the user select a value - callback: A callback to execute on the form submit. It will take as parameter the selected object. - choosingText: The label of the select input. - customizationBlock: An optional block to customize the text field of the select widget. It will take the mdl brush as parameter and the html canvas. - description: An optional tooltip for the input. - labelBlock: A block taking in parameter an object and returning a label to show in the input. - possibilities: The list of possibilities. - selectedObject: An optional object to select by default. - sortBlock: An optional block to sort the objects. - - -Implementation Points -------------------- - -I act as a select by in fact this is just a trick. In reality I am just an text field in read only. The user cannot enter text but he can select an element of a list. The selected element will replace the text in the input. - -To use the callback I keep a temporary dictionary of all the labels and the associated objects. I should ALWAYS have only one object by label. In case the label block return an existing label, I will add a `(X)` to the label where X is the number of occurences. -" -Class { - #name : #MDLSelectWidget, - #superclass : #MDLWidget, - #instVars : [ - 'choosingText', - 'labelBlock', - 'callback', - 'selectedObject', - 'possibilities', - 'description', - 'sortBlock', - 'autoSubmit', - 'customizationBlock', - 'entryTooltip' - ], - #category : #'Material-Design-Lite-Widgets-Form' -} - -{ #category : #'instance creation' } -MDLSelectWidget class >> possibilities: aColl inputLabel: aLabel labelBlock: aLabelBlock callback: aBlock [ - ^ self - possibilities: aColl - inputLabel: aLabel - labelBlock: aLabelBlock - callback: aBlock - selectedObject: nil -] - -{ #category : #'instance creation' } -MDLSelectWidget class >> possibilities: aColl inputLabel: aLabel labelBlock: aLabelBlock callback: aBlock selectedObject: anObject [ - ^ self - possibilities: aColl - inputLabel: aLabel - labelBlock: aLabelBlock - callback: aBlock - selectedObject: anObject - tooltip: nil -] - -{ #category : #'instance creation' } -MDLSelectWidget class >> possibilities: aColl inputLabel: aLabel labelBlock: aLabelBlock callback: aBlock selectedObject: anObject tooltip: aString [ - ^ self - possibilities: aColl - inputLabel: aLabel - labelBlock: aLabelBlock - callback: aBlock - selectedObject: anObject - tooltip: aString - sortBlock: nil -] - -{ #category : #'instance creation' } -MDLSelectWidget class >> possibilities: aColl inputLabel: aLabel labelBlock: aLabelBlock callback: aBlock selectedObject: anObject tooltip: aString sortBlock: aSortBlock [ - ^ self new - choosingText: aLabel; - labelBlock: aLabelBlock; - callback: aBlock; - selectedObject: anObject; - possibilities: aColl; - description: aString; - sortBlock: aSortBlock; - yourself -] - -{ #category : #'labelMap - generation' } -MDLSelectWidget >> addLabelMapEntryFor: anElem version: anInteger into: aDictionary [ - | label | - label := self labelFor: anElem version: anInteger. - aDictionary at: label ifPresent: [ :lab | self addLabelMapEntryFor: anElem version: anInteger + 1 into: aDictionary ] ifAbsent: [ aDictionary at: label put: anElem ]. - self flag: #pharo6. "at:ifPresent:ifAbsentPut: is only available in Pharo 6 :( Improve this when the minimal Pharo version required will be Pharo 6." - ^ aDictionary -] - -{ #category : #accessing } -MDLSelectWidget >> autoSubmit [ - ^ autoSubmit ifNil: [ autoSubmit := false ] -] - -{ #category : #accessing } -MDLSelectWidget >> autoSubmit: anObject [ - autoSubmit := anObject -] - -{ #category : #'public api' } -MDLSelectWidget >> beAutoSubmit [ - "With this option the select widget will submit on a user selection. Do not forget to put your widget in a form." - - self autoSubmit: true -] - -{ #category : #'labelMap - generation' } -MDLSelectWidget >> buildLabelMap [ - ^ self possibilities - inject: OrderedDictionary new - into: [ :dico :elem | self addLabelMapEntryFor: elem version: 0 into: dico ] -] - -{ #category : #accessing } -MDLSelectWidget >> callback [ - ^ callback -] - -{ #category : #'public api' } -MDLSelectWidget >> callback: aBlockOrSymbol [ - "Callback to execute on the form submit." - - callback := aBlockOrSymbol -] - -{ #category : #accessing } -MDLSelectWidget >> choosingText [ - ^ choosingText -] - -{ #category : #'public api' } -MDLSelectWidget >> choosingText: aString [ - "The label of the select input." - - choosingText := aString -] - -{ #category : #accessing } -MDLSelectWidget >> customizationBlock [ - ^ customizationBlock -] - -{ #category : #accessing } -MDLSelectWidget >> customizationBlock: anObject [ - customizationBlock := anObject -] - -{ #category : #accessing } -MDLSelectWidget >> defaultValueBasedOn: aLabelMap [ - (self selectedObject isNil and: [ self possibilities isEmpty ]) ifTrue: [ ^ nil ]. - - ^ aLabelMap - keyAtValue: (self selectedObject ifNil: [ self possibilities first ]) - ifAbsent: [ self error: 'The selected object is not in the possibilities collection.' ] -] - -{ #category : #accessing } -MDLSelectWidget >> description [ - ^ description -] - -{ #category : #'public api' } -MDLSelectWidget >> description: aString [ - "An optional tooltip for the input." - - description := aString -] - -{ #category : #accessing } -MDLSelectWidget >> entryTooltip [ - ^ entryTooltip -] - -{ #category : #accessing } -MDLSelectWidget >> entryTooltip: aBlockOrSymbol [ - entryTooltip := aBlockOrSymbol -] - -{ #category : #private } -MDLSelectWidget >> idForMenuItemLabelled: aLabel inSelectWith: anId [ - ^ anId , 'entry' , aLabel -] - -{ #category : #initialization } -MDLSelectWidget >> initialize [ - super initialize. - - "In case the user does not set any possibilities, show a disable select widget instead of throwing an error during the redering because the possibilities are nil instead of an empty collection." - possibilities := #() -] - -{ #category : #javascript } -MDLSelectWidget >> jsSelectInitialization [ - ^ 'getmdlSelect.init("#' , self id , '");' - " this ->'document.addEventListener('DOMNodeInserted', function (ev) { componentHandler.upgradeDom(); }, false);' must never add. It's bad pratice. - Launch yourself componentHandler.upgradeDom() OR add ONLY ONE TIME at the document this eventListener" -] - -{ #category : #accessing } -MDLSelectWidget >> labelBlock [ - ^ labelBlock -] - -{ #category : #'public api' } -MDLSelectWidget >> labelBlock: aBlockOrSymbol [ - "A block taking in parameter an object and returning a label to show in the input." - - labelBlock := aBlockOrSymbol -] - -{ #category : #accessing } -MDLSelectWidget >> labelFor: anObject [ - ^ self labelBlock ifNil: [ anObject asString ] ifNotNil: [ :blk | blk value: anObject ] -] - -{ #category : #'labelMap - generation' } -MDLSelectWidget >> labelFor: anElem version: anInteger [ - ^ String - streamContents: [ :s | - s nextPutAll: (self labelFor: anElem). - anInteger = 0 - ifFalse: [ s - nextPutAll: ' ('; - print: anInteger; - nextPut: $) ] ] -] - -{ #category : #'public api - seaside compatibility' } -MDLSelectWidget >> labels: aBlockOrSymbol [ - "This method is here to match at least a minimum with the seaside select API." - - self labelBlock: aBlockOrSymbol -] - -{ #category : #'public api - seaside compatibility' } -MDLSelectWidget >> list: aCollection [ - "This method is here to match at least a minimum with the seaside select API." - - self possibilities: aCollection -] - -{ #category : #accessing } -MDLSelectWidget >> possibilities [ - ^ possibilities -] - -{ #category : #'public api' } -MDLSelectWidget >> possibilities: aCollection [ - "The list of possibilities." - - possibilities := aCollection -] - -{ #category : #rendering } -MDLSelectWidget >> renderArrowIconFor: anId on: html [ - html label - for: anId; - with: [ html mdlIcon - toggle; - with: #keyboard_arrow_down ] -] - -{ #category : #rendering } -MDLSelectWidget >> renderContentOn: html [ - self ensureId: html. - html mdlTextFieldContainer - class: #'mdl-select'; - id: self id; - floatingLabel; - with: [ | fieldId labelMap | - self - renderTextFieldFor: (fieldId := html nextId) withMap: (labelMap := self buildLabelMap) on: html; - renderArrowIconFor: fieldId on: html; - renderLabelFor: fieldId on: html; - renderPossibilitiesFor: fieldId withMap: labelMap on: html; - renderTooltipFor: fieldId on: html. - labelMap keysAndValuesDo: [ :label :object | self renderMenuTooltipFor: object at: (self idForMenuItemLabelled: label inSelectWith: fieldId) on: html ] ]. - html script: self jsSelectInitialization -] - -{ #category : #rendering } -MDLSelectWidget >> renderLabelFor: anId on: html [ - self choosingText isEmptyOrNil ifTrue: [ ^ self ]. - - html mdlTextFieldLabel - for: anId; - with: self choosingText -] - -{ #category : #rendering } -MDLSelectWidget >> renderMenuTooltipFor: anItem at: anId on: html [ - | helpText | - (self entryTooltip isNil or: [ self entryTooltip argumentCount = 1 and: [ (helpText := self entryTooltip value: anItem) isEmptyOrNil ] ]) ifTrue: [ ^ self ]. - - html mdlTooltip - large; - for: anId; - with: - (self entryTooltip argumentCount = 1 - ifTrue: [ helpText ] - ifFalse: [ self entryTooltip mdlCull: anItem cull: html ]) -] - -{ #category : #rendering } -MDLSelectWidget >> renderPossibilitiesFor: anId withMap: aLabelMap on: html [ - aLabelMap ifEmpty: [ ^ self ]. - - html mdlMenu - for: anId; - bottomLeft; - with: [ (self sortBlock ifNil: [ aLabelMap keys ] ifNotNil: [ :blk | aLabelMap keys sort: blk ]) - do: [ :label | - html mdlMenuItem - id: (self idForMenuItemLabelled: label inSelectWith: anId); - with: label ] ] -] - -{ #category : #rendering } -MDLSelectWidget >> renderTextFieldFor: anId withMap: aLabelMap on: html [ - | textField | - (textField := html mdlTextFieldInput) - id: anId; - value: (self defaultValueBasedOn: aLabelMap); - disabled: self possibilities isEmpty; - readonly: true; - tabIndex: '-1'; - noAutocomplete; - callback: [ :input | self callback ifNotNil: [ :cb | cb value: (aLabelMap at: input) ] ]; - onChange: 'submit()' if: self autoSubmit; - type: 'text'. - self customizationBlock ifNotNil: [ :bl | bl mdlCull: textField cull: html ] -] - -{ #category : #rendering } -MDLSelectWidget >> renderTooltipFor: anId on: html [ - self description ifNil: [ ^ self ]. - - html mdlTooltip - for: anId; - large; - with: - (self description isBlock - ifTrue: [ self description value: html ] - ifFalse: [ self description ]) -] - -{ #category : #'public api - seaside compatibility' } -MDLSelectWidget >> selected: anObject [ - "This method is here to match at least a minimum with the seaside select API." - - self selectedObject: anObject -] - -{ #category : #accessing } -MDLSelectWidget >> selectedObject [ - ^ selectedObject value -] - -{ #category : #'public api' } -MDLSelectWidget >> selectedObject: anObject [ - "An optional object to select by default." - - selectedObject := anObject -] - -{ #category : #accessing } -MDLSelectWidget >> sortBlock [ - ^ sortBlock -] - -{ #category : #'public api' } -MDLSelectWidget >> sortBlock: aBlock [ - "An optional block to sort the objects." - - sortBlock := aBlock -] - -{ #category : #'public api' } -MDLSelectWidget >> standardSorting [ - "Use the default #<= on the objects values directly." - - self sortBlock: [ :a :b | a value <= b value ] -] +" +I am a widget trying to reproduce the behavior of a select input of a form with a WDL compatible design. + +Description +-------------------- + +I am a widget with a list of possibilities that can select the user. + +I MUST be used inside a form and I will execute a callback on the submit. + +I have a tricky implementation, for more informations check the implementations detail at the end of the comment. + +Public API and Key Messages +-------------------- + +There is many constructors in my class side. + +- #defaultSorting Use this method to sort the labels using the #<= operator by default +- #beAutoSubmit Use this method if you want to form to submit when the user select a value. Do not forget to put your widget in a form. + +Examples +------------------- + + MDLSelectWidget new + possibilities: #(1 2 3 4 5 5); + labelBlock: [ :number | number = 5 ifTrue: [ '0' ] ifFalse: [ (number - 1) asString ] ]; + choosingText: 'Select Your Number'; + selectedObject: 3; + defaultSorting; + callback: [ :input | Transcript << input; cr ]; + description: 'description'; + beAutoSubmit; + yourself. + + + MDLSelectWidget + possibilities: #(1 2 3 4 5 5) + inputLabel: 'Select Your Number' + labelBlock: [ :number | number = 5 ifTrue: [ '0' ] ifFalse: [ (number - 1) asString ] ] + callback: [ :input | Transcript << input; cr ] + selectedObject: 3 + tooltip: 'description' + sortBlock: [ :a :b | a > b ] + +Internal Representation and Key Implementation Points. +------------------- + + Instance Variables + autoSubmit: If true, the form will be submit when the user select a value + callback: A callback to execute on the form submit. It will take as parameter the selected object. + choosingText: The label of the select input. + customizationBlock: An optional block to customize the text field of the select widget. It will take the mdl brush as parameter and the html canvas. + description: An optional tooltip for the input. + labelBlock: A block taking in parameter an object and returning a label to show in the input. + possibilities: The list of possibilities. + selectedObject: An optional object to select by default. + sortBlock: An optional block to sort the objects. + + +Implementation Points +------------------- + +I act as a select by in fact this is just a trick. In reality I am just an text field in read only. The user cannot enter text but he can select an element of a list. The selected element will replace the text in the input. + +To use the callback I keep a temporary dictionary of all the labels and the associated objects. I should ALWAYS have only one object by label. In case the label block return an existing label, I will add a `(X)` to the label where X is the number of occurences. +" +Class { + #name : #MDLSelectWidget, + #superclass : #MDLWidget, + #instVars : [ + 'choosingText', + 'labelBlock', + 'callback', + 'selectedObject', + 'possibilities', + 'description', + 'sortBlock', + 'autoSubmit', + 'customizationBlock', + 'entryTooltip' + ], + #category : #'Material-Design-Lite-Widgets-Form' +} + +{ #category : #'instance creation' } +MDLSelectWidget class >> possibilities: aColl inputLabel: aLabel labelBlock: aLabelBlock callback: aBlock [ + ^ self + possibilities: aColl + inputLabel: aLabel + labelBlock: aLabelBlock + callback: aBlock + selectedObject: nil +] + +{ #category : #'instance creation' } +MDLSelectWidget class >> possibilities: aColl inputLabel: aLabel labelBlock: aLabelBlock callback: aBlock selectedObject: anObject [ + ^ self + possibilities: aColl + inputLabel: aLabel + labelBlock: aLabelBlock + callback: aBlock + selectedObject: anObject + tooltip: nil +] + +{ #category : #'instance creation' } +MDLSelectWidget class >> possibilities: aColl inputLabel: aLabel labelBlock: aLabelBlock callback: aBlock selectedObject: anObject tooltip: aString [ + ^ self + possibilities: aColl + inputLabel: aLabel + labelBlock: aLabelBlock + callback: aBlock + selectedObject: anObject + tooltip: aString + sortBlock: nil +] + +{ #category : #'instance creation' } +MDLSelectWidget class >> possibilities: aColl inputLabel: aLabel labelBlock: aLabelBlock callback: aBlock selectedObject: anObject tooltip: aString sortBlock: aSortBlock [ + ^ self new + choosingText: aLabel; + labelBlock: aLabelBlock; + callback: aBlock; + selectedObject: anObject; + possibilities: aColl; + description: aString; + sortBlock: aSortBlock; + yourself +] + +{ #category : #'labelMap - generation' } +MDLSelectWidget >> addLabelMapEntryFor: anElem version: anInteger into: aDictionary [ + | label | + label := self labelFor: anElem version: anInteger. + aDictionary at: label ifPresent: [ :lab | self addLabelMapEntryFor: anElem version: anInteger + 1 into: aDictionary ] ifAbsent: [ aDictionary at: label put: anElem ]. + self flag: #pharo6. "at:ifPresent:ifAbsentPut: is only available in Pharo 6 :( Improve this when the minimal Pharo version required will be Pharo 6." + ^ aDictionary +] + +{ #category : #accessing } +MDLSelectWidget >> autoSubmit [ + ^ autoSubmit ifNil: [ autoSubmit := false ] +] + +{ #category : #accessing } +MDLSelectWidget >> autoSubmit: anObject [ + autoSubmit := anObject +] + +{ #category : #'public api' } +MDLSelectWidget >> beAutoSubmit [ + "With this option the select widget will submit on a user selection. Do not forget to put your widget in a form." + + self autoSubmit: true +] + +{ #category : #'labelMap - generation' } +MDLSelectWidget >> buildLabelMap [ + ^ self possibilities + inject: OrderedDictionary new + into: [ :dico :elem | self addLabelMapEntryFor: elem version: 0 into: dico ] +] + +{ #category : #accessing } +MDLSelectWidget >> callback [ + ^ callback +] + +{ #category : #'public api' } +MDLSelectWidget >> callback: aBlockOrSymbol [ + "Callback to execute on the form submit." + + callback := aBlockOrSymbol +] + +{ #category : #accessing } +MDLSelectWidget >> choosingText [ + ^ choosingText +] + +{ #category : #'public api' } +MDLSelectWidget >> choosingText: aString [ + "The label of the select input." + + choosingText := aString +] + +{ #category : #accessing } +MDLSelectWidget >> customizationBlock [ + ^ customizationBlock +] + +{ #category : #accessing } +MDLSelectWidget >> customizationBlock: anObject [ + customizationBlock := anObject +] + +{ #category : #accessing } +MDLSelectWidget >> defaultValueBasedOn: aLabelMap [ + (self selectedObject isNil and: [ self possibilities isEmpty ]) ifTrue: [ ^ nil ]. + + ^ aLabelMap + keyAtValue: (self selectedObject ifNil: [ self possibilities first ]) + ifAbsent: [ self error: 'The selected object is not in the possibilities collection.' ] +] + +{ #category : #accessing } +MDLSelectWidget >> description [ + ^ description +] + +{ #category : #'public api' } +MDLSelectWidget >> description: aString [ + "An optional tooltip for the input." + + description := aString +] + +{ #category : #accessing } +MDLSelectWidget >> entryTooltip [ + ^ entryTooltip +] + +{ #category : #accessing } +MDLSelectWidget >> entryTooltip: aBlockOrSymbol [ + entryTooltip := aBlockOrSymbol +] + +{ #category : #private } +MDLSelectWidget >> idForMenuItemLabelled: aLabel inSelectWith: anId [ + ^ anId , 'entry' , aLabel +] + +{ #category : #initialization } +MDLSelectWidget >> initialize [ + super initialize. + + "In case the user does not set any possibilities, show a disable select widget instead of throwing an error during the redering because the possibilities are nil instead of an empty collection." + possibilities := #() +] + +{ #category : #javascript } +MDLSelectWidget >> jsSelectInitialization [ + ^ 'getmdlSelect.init("#' , self id , '");' + " this ->'document.addEventListener('DOMNodeInserted', function (ev) { componentHandler.upgradeDom(); }, false);' must never add. It's bad pratice. + Launch yourself componentHandler.upgradeDom() OR add ONLY ONE TIME at the document this eventListener" +] + +{ #category : #accessing } +MDLSelectWidget >> labelBlock [ + ^ labelBlock +] + +{ #category : #'public api' } +MDLSelectWidget >> labelBlock: aBlockOrSymbol [ + "A block taking in parameter an object and returning a label to show in the input." + + labelBlock := aBlockOrSymbol +] + +{ #category : #accessing } +MDLSelectWidget >> labelFor: anObject [ + ^ self labelBlock ifNil: [ anObject asString ] ifNotNil: [ :blk | blk value: anObject ] +] + +{ #category : #'labelMap - generation' } +MDLSelectWidget >> labelFor: anElem version: anInteger [ + ^ String + streamContents: [ :s | + s nextPutAll: (self labelFor: anElem). + anInteger = 0 + ifFalse: [ s + nextPutAll: ' ('; + print: anInteger; + nextPut: $) ] ] +] + +{ #category : #'public api - seaside compatibility' } +MDLSelectWidget >> labels: aBlockOrSymbol [ + "This method is here to match at least a minimum with the seaside select API." + + self labelBlock: aBlockOrSymbol +] + +{ #category : #'public api - seaside compatibility' } +MDLSelectWidget >> list: aCollection [ + "This method is here to match at least a minimum with the seaside select API." + + self possibilities: aCollection +] + +{ #category : #accessing } +MDLSelectWidget >> possibilities [ + ^ possibilities +] + +{ #category : #'public api' } +MDLSelectWidget >> possibilities: aCollection [ + "The list of possibilities." + + possibilities := aCollection +] + +{ #category : #rendering } +MDLSelectWidget >> renderArrowIconFor: anId on: html [ + html label + for: anId; + with: [ html mdlIcon + toggle; + with: #keyboard_arrow_down ] +] + +{ #category : #rendering } +MDLSelectWidget >> renderContentOn: html [ + self ensureId: html. + html mdlTextFieldContainer + class: #'mdl-select'; + id: self id; + floatingLabel; + with: [ | fieldId labelMap | + self + renderTextFieldFor: (fieldId := html nextId) withMap: (labelMap := self buildLabelMap) on: html; + renderArrowIconFor: fieldId on: html; + renderLabelFor: fieldId on: html; + renderPossibilitiesFor: fieldId withMap: labelMap on: html; + renderTooltipFor: fieldId on: html. + labelMap keysAndValuesDo: [ :label :object | self renderMenuTooltipFor: object at: (self idForMenuItemLabelled: label inSelectWith: fieldId) on: html ] ]. + html script: self jsSelectInitialization +] + +{ #category : #rendering } +MDLSelectWidget >> renderLabelFor: anId on: html [ + self choosingText isEmptyOrNil ifTrue: [ ^ self ]. + + html mdlTextFieldLabel + for: anId; + with: self choosingText +] + +{ #category : #rendering } +MDLSelectWidget >> renderMenuTooltipFor: anItem at: anId on: html [ + | helpText | + (self entryTooltip isNil or: [ self entryTooltip argumentCount = 1 and: [ (helpText := self entryTooltip value: anItem) isEmptyOrNil ] ]) ifTrue: [ ^ self ]. + + html mdlTooltip + large; + for: anId; + with: + (self entryTooltip argumentCount = 1 + ifTrue: [ helpText ] + ifFalse: [ self entryTooltip mdlCull: anItem cull: html ]) +] + +{ #category : #rendering } +MDLSelectWidget >> renderPossibilitiesFor: anId withMap: aLabelMap on: html [ + aLabelMap ifEmpty: [ ^ self ]. + + html mdlMenu + for: anId; + bottomLeft; + with: [ (self sortBlock ifNil: [ aLabelMap keys ] ifNotNil: [ :blk | aLabelMap keys sort: blk ]) + do: [ :label | + html mdlMenuItem + id: (self idForMenuItemLabelled: label inSelectWith: anId); + with: label ] ] +] + +{ #category : #rendering } +MDLSelectWidget >> renderTextFieldFor: anId withMap: aLabelMap on: html [ + | textField | + (textField := html mdlTextFieldInput) + id: anId; + value: (self defaultValueBasedOn: aLabelMap); + disabled: self possibilities isEmpty; + readonly: true; + tabIndex: '-1'; + noAutocomplete; + callback: [ :input | self callback ifNotNil: [ :cb | cb value: (aLabelMap at: input) ] ]; + onChange: 'submit()' if: self autoSubmit; + type: 'text'. + self customizationBlock ifNotNil: [ :bl | bl mdlCull: textField cull: html ] +] + +{ #category : #rendering } +MDLSelectWidget >> renderTooltipFor: anId on: html [ + self description ifNil: [ ^ self ]. + + html mdlTooltip + for: anId; + large; + with: + (self description isBlock + ifTrue: [ self description value: html ] + ifFalse: [ self description ]) +] + +{ #category : #'public api - seaside compatibility' } +MDLSelectWidget >> selected: anObject [ + "This method is here to match at least a minimum with the seaside select API." + + self selectedObject: anObject +] + +{ #category : #accessing } +MDLSelectWidget >> selectedObject [ + ^ selectedObject value +] + +{ #category : #'public api' } +MDLSelectWidget >> selectedObject: anObject [ + "An optional object to select by default." + + selectedObject := anObject +] + +{ #category : #accessing } +MDLSelectWidget >> sortBlock [ + ^ sortBlock +] + +{ #category : #'public api' } +MDLSelectWidget >> sortBlock: aBlock [ + "An optional block to sort the objects." + + sortBlock := aBlock +] + +{ #category : #'public api' } +MDLSelectWidget >> standardSorting [ + "Use the default #<= on the objects values directly." + + self sortBlock: [ :a :b | a value <= b value ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLSimpleDrawerSection.class.st b/src/Material-Design-Lite-Widgets/MDLSimpleDrawerSection.class.st index 1eb2960a..422f3522 100644 --- a/src/Material-Design-Lite-Widgets/MDLSimpleDrawerSection.class.st +++ b/src/Material-Design-Lite-Widgets/MDLSimpleDrawerSection.class.st @@ -1,12 +1,12 @@ -Class { - #name : #MDLSimpleDrawerSection, - #superclass : #MDLLinkingLayoutSection, - #category : 'Material-Design-Lite-Widgets-Header' -} - -{ #category : #'as yet unclassified' } -MDLSimpleDrawerSection >> renderContentOn: html [ - html mdlLayoutDrawer: [ - html mdlLayoutTitle: layout title. - self renderLinksOn: html ] -] +Class { + #name : #MDLSimpleDrawerSection, + #superclass : #MDLLinkingLayoutSection, + #category : 'Material-Design-Lite-Widgets-Header' +} + +{ #category : #'as yet unclassified' } +MDLSimpleDrawerSection >> renderContentOn: html [ + html mdlLayoutDrawer: [ + html mdlLayoutTitle: layout title. + self renderLinksOn: html ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLSimpleRowHeaderSection.class.st b/src/Material-Design-Lite-Widgets/MDLSimpleRowHeaderSection.class.st index fe61ad49..fd9d8768 100644 --- a/src/Material-Design-Lite-Widgets/MDLSimpleRowHeaderSection.class.st +++ b/src/Material-Design-Lite-Widgets/MDLSimpleRowHeaderSection.class.st @@ -1,15 +1,15 @@ -Class { - #name : #MDLSimpleRowHeaderSection, - #superclass : #MDLAbstractHeaderSection, - #category : 'Material-Design-Lite-Widgets-Header' -} - -{ #category : #rendering } -MDLSimpleRowHeaderSection >> renderContentOn: html [ - (html brush: brush) - with: [ - html - mdlLayoutHeaderRow: [ - html mdlLayoutTitle: layout title. - self renderLinksOn: html ] ] -] +Class { + #name : #MDLSimpleRowHeaderSection, + #superclass : #MDLAbstractHeaderSection, + #category : 'Material-Design-Lite-Widgets-Header' +} + +{ #category : #rendering } +MDLSimpleRowHeaderSection >> renderContentOn: html [ + (html brush: brush) + with: [ + html + mdlLayoutHeaderRow: [ + html mdlLayoutTitle: layout title. + self renderLinksOn: html ] ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLSmallFooter.class.st b/src/Material-Design-Lite-Widgets/MDLSmallFooter.class.st index 109833d0..47e7ddd5 100644 --- a/src/Material-Design-Lite-Widgets/MDLSmallFooter.class.st +++ b/src/Material-Design-Lite-Widgets/MDLSmallFooter.class.st @@ -1,44 +1,44 @@ -" -I'm a Mini Footer. -In this implementation, leftSection is a Dictionary (title -> { label -> url }). -The right section must be a Collection of WAComponents that will be rendered on the right side. -" -Class { - #name : #MDLSmallFooter, - #superclass : #MDLWidget, - #instVars : [ - 'leftSection', - 'rightSection' - ], - #category : #'Material-Design-Lite-Widgets-Footer' -} - -{ #category : #initialization } -MDLSmallFooter >> initialize [ - super initialize. - leftSection := MDLFooterNilSection new. - rightSection := MDLFooterNilSection new -] - -{ #category : #adding } -MDLSmallFooter >> onLeftSideAddLinks: links [ - "Links must be formatted as following : (header -> #((label1->url1) . (label2 -> url2)))" - leftSection isNilSection - ifTrue: [ leftSection := MDLFooterLinksSection new ]. - leftSection := leftSection addLinksList: (MDLMiniFooterLinksList new addLinks: links; yourself) -] - -{ #category : #adding } -MDLSmallFooter >> onRightSideAddComponents: components [ - "Components must be an array of WAComponents (render: will be called on them)" - rightSection isNilSection - ifTrue: [ rightSection := MDLFooterComponentsSection new ]. - rightSection := rightSection addComponents: components -] - -{ #category : #rendering } -MDLSmallFooter >> renderContentOn: html [ - html mdlMiniFooter: [ - html mdlMiniFooterLeftSection: [ leftSection renderSectionOn: html ]. - html mdlMiniFooterRightSection: [ rightSection renderSectionOn: html ] ] -] +" +I'm a Mini Footer. +In this implementation, leftSection is a Dictionary (title -> { label -> url }). +The right section must be a Collection of WAComponents that will be rendered on the right side. +" +Class { + #name : #MDLSmallFooter, + #superclass : #MDLWidget, + #instVars : [ + 'leftSection', + 'rightSection' + ], + #category : #'Material-Design-Lite-Widgets-Footer' +} + +{ #category : #initialization } +MDLSmallFooter >> initialize [ + super initialize. + leftSection := MDLFooterNilSection new. + rightSection := MDLFooterNilSection new +] + +{ #category : #adding } +MDLSmallFooter >> onLeftSideAddLinks: links [ + "Links must be formatted as following : (header -> #((label1->url1) . (label2 -> url2)))" + leftSection isNilSection + ifTrue: [ leftSection := MDLFooterLinksSection new ]. + leftSection := leftSection addLinksList: (MDLMiniFooterLinksList new addLinks: links; yourself) +] + +{ #category : #adding } +MDLSmallFooter >> onRightSideAddComponents: components [ + "Components must be an array of WAComponents (render: will be called on them)" + rightSection isNilSection + ifTrue: [ rightSection := MDLFooterComponentsSection new ]. + rightSection := rightSection addComponents: components +] + +{ #category : #rendering } +MDLSmallFooter >> renderContentOn: html [ + html mdlMiniFooter: [ + html mdlMiniFooterLeftSection: [ leftSection renderSectionOn: html ]. + html mdlMiniFooterRightSection: [ rightSection renderSectionOn: html ] ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLSortableTable.class.st b/src/Material-Design-Lite-Widgets/MDLSortableTable.class.st index 30d027d6..7130e828 100644 --- a/src/Material-Design-Lite-Widgets/MDLSortableTable.class.st +++ b/src/Material-Design-Lite-Widgets/MDLSortableTable.class.st @@ -1,326 +1,326 @@ -" -Sortable table, renders a table and adds the necessary behavior to navigate trough the table - - Instance Variables - elementsToShow: number of rows that will be rendered - header: a table with the table headers ( auto conversion from object ) - position: the index of the first row to render - rows: a table with all the rows - selectable: a boolean saying that the cells can be selected or not - ajaxOnCompleteHook: a String containing some JS code to be executed after we changed of page. By default it will update the MDL components to initialize the new ones. -" -Class { - #name : #MDLSortableTable, - #superclass : #WAComponent, - #instVars : [ - 'title', - 'header', - 'rows', - 'elementsToShow', - 'unsortedRows', - 'position', - 'rowsPerPagePossibilities', - 'selectable', - 'id', - 'ajaxOnCompleteHook', - 'tableStyle', - 'rowsCache' - ], - #category : #'Material-Design-Lite-Widgets-Table' -} - -{ #category : #accessing } -MDLSortableTable >> ajaxOnCompleteHook [ - "I am a hook to let the user add some javascript after the rendering of a new page. By default I will update the MDL components to initialize the new ones that might be in the table if needed." - - ^ ajaxOnCompleteHook ifNil: [ 'componentHandler.upgradeDom();' ] -] - -{ #category : #accessing } -MDLSortableTable >> ajaxOnCompleteHook: anObject [ - ajaxOnCompleteHook := anObject -] - -{ #category : #javascript } -MDLSortableTable >> ajaxUpdateScriptFrom: html [ - ^ html jQuery - script: [ :s | - s - << - ((html jQuery id: id) load - html: [ :ajaxHtml | self renderTableContentOn: ajaxHtml ]; - onComplete: self ajaxOnCompleteHook) ] -] - -{ #category : #accessing } -MDLSortableTable >> elementsToShow [ - ^ elementsToShow -] - -{ #category : #accessing } -MDLSortableTable >> elementsToShow: anObject [ - elementsToShow := anObject -] - -{ #category : #rendering } -MDLSortableTable >> ensureCurrentPageIsVisible [ - "In some case the elements to show can change. If we currently are in a page that does not exist anymore since the number of elements decreased, we should reset the position." - - self position > rowsCache size - ifTrue: [ self position: 1 ] -] - -{ #category : #accessing } -MDLSortableTable >> header [ - ^ header -] - -{ #category : #accessing } -MDLSortableTable >> header: aCollection [ - header := aCollection collect: [ :each | each asMDLSortableTableHeader ] -] - -{ #category : #rendering } -MDLSortableTable >> indexOfLastRowToShow [ - ^ rowsCache size min: position + elementsToShow - 1 -] - -{ #category : #initialization } -MDLSortableTable >> initialize [ - super initialize. - position := 1. - rows := #(). - header := #(). - unsortedRows := #(). - self rowsPerPagePossibilities: #(10 50 100). - selectable := false -] - -{ #category : #actions } -MDLSortableTable >> nextPosition [ - position + elementsToShow < rowsCache size - ifTrue: [ self position: position + elementsToShow ] -] - -{ #category : #accessing } -MDLSortableTable >> noPagination [ - self rowsPerPagePossibilities: {(Float infinity)} -] - -{ #category : #accessing } -MDLSortableTable >> position [ - ^ position -] - -{ #category : #accessing } -MDLSortableTable >> position: anObject [ - position := anObject -] - -{ #category : #actions } -MDLSortableTable >> previousPosition [ - self position: ((position - elementsToShow) max: 1) -] - -{ #category : #rendering } -MDLSortableTable >> renderButtonTriggering: aMethod withIcon: aSymbol disabled: isDisabled on: html [ - html mdlButton - bePush; - colored; - icon; - disabled: isDisabled; - onClick: [ html jQuery ajax - callback: [ self perform: aMethod ]; - onSuccess: (self ajaxUpdateScriptFrom: html) ] - if: isDisabled not; - with: [ html mdlIcon: aSymbol ] -] - -{ #category : #rendering } -MDLSortableTable >> renderContentOn: html [ - html mdlGrid - class: 'mdl-sorted-table'; - with: [ html mdlCard - shadow: 2; - class: 'mdl-sorted-table__wrapper'; - class: self tableStyle if: self tableStyle isNotNil; - id: (id := html nextId); - with: [ self renderTableContentOn: html ] ] -] - -{ #category : #rendering } -MDLSortableTable >> renderFooterPaginationOn: html [ - html mdlCardTextContainer - class: 'mdl-sorted-table__footer'; - with: [ - html div - mdlTypographyTextRight; - with: [ - html text: 'Rows per page: '. - self renderItemsByPageSelectionComponentOn: html. - self renderPagesInfoOn: html. - self - renderButtonTriggering: #previousPosition - withIcon: #keyboard_arrow_left - disabled: position = 1 - on: html. - self - renderButtonTriggering: #nextPosition - withIcon: #keyboard_arrow_right - disabled: position + elementsToShow > rowsCache size - on: html ] ] -] - -{ #category : #rendering } -MDLSortableTable >> renderHeaderOn: html [ - html - tableHead: [ html tableRow: [ header doWithIndex: [ :head :i | head renderContentOn: html forTable: self columnIndex: i ] ] ] -] - -{ #category : #accessing } -MDLSortableTable >> renderItemsByPageSelectionComponentOn: html [ - html - render: - (MDLSelectWidget new - labelBlock: #asString; - possibilities: rowsPerPagePossibilities; - callback: [ :o | self elementsToShow: o ]; - selectedObject: self elementsToShow; - sortBlock: [ :a :b | a asInteger <= b asInteger ]; - customizationBlock: [ :textField :renderer | textField onChange: (html jQuery ajax serializeThis onComplete: (self ajaxUpdateScriptFrom: html)) ]; - yourself) -] - -{ #category : #rendering } -MDLSortableTable >> renderPagesInfoOn: html [ - html - text: - (String - streamContents: [ :s | - s - print: position; - nextPutAll: ' - '; - print: self indexOfLastRowToShow; - nextPutAll: ' of '; - print: rowsCache size ]) -] - -{ #category : #rendering } -MDLSortableTable >> renderRowContentFor: cells on: html [ - header - doWithIndex: [ :headerCell :columnIndex | - | cell | - (headerCell tableCellOn: html) - with: - ((cell := cells at: columnIndex) isBlock - ifTrue: [ [ cell cull: html ] ] - ifFalse: [ cell ]) ] -] - -{ #category : #rendering } -MDLSortableTable >> renderRowsOn: html [ - ((position to: self indexOfLastRowToShow) collect: [ :rowIndex | rowsCache at: rowIndex ]) - do: [ :cells | html tableRow: [ self renderRowContentFor: cells on: html ] ] -] - -{ #category : #rendering } -MDLSortableTable >> renderTableContentOn: html [ - "We cache the rows because it is possible that the user give a block to execute." - - rowsCache := self rows. - self ensureCurrentPageIsVisible. - html div - class: 'mdl-sorted-table__content'; - with: [ self title ifNotNil: [ :t | html mdlCardTitleContainer: [ html mdlCardTitleText: t level: 2 ] ]. - (selectable - ifTrue: [ html mdlTable selectable ] - ifFalse: [ html mdlTable ]) - with: [ self renderHeaderOn: html. - self renderRowsOn: html ] ]. - self shouldDisplayPagination ifTrue: [ self renderFooterPaginationOn: html ] -] - -{ #category : #accessing } -MDLSortableTable >> rows [ - ^ rows value -] - -{ #category : #accessing } -MDLSortableTable >> rows: anObject [ - rows := anObject. - unsortedRows := anObject -] - -{ #category : #accessing } -MDLSortableTable >> rowsPerPagePossibilities [ - ^ rowsPerPagePossibilities -] - -{ #category : #accessing } -MDLSortableTable >> rowsPerPagePossibilities: aCollection [ - rowsPerPagePossibilities := aCollection. - aCollection ifNotEmpty: [ self elementsToShow: aCollection first ] -] - -{ #category : #accessing } -MDLSortableTable >> selectable [ - ^ selectable -] - -{ #category : #accessing } -MDLSortableTable >> selectable: anObject [ - selectable := anObject -] - -{ #category : #testing } -MDLSortableTable >> shouldDisplayPagination [ - ^ self rowsPerPagePossibilities min < rowsCache size -] - -{ #category : #sorting } -MDLSortableTable >> sortAscendingAtRow: aRowIndex [ - self sortAtRow: aRowIndex using: #> -] - -{ #category : #sorting } -MDLSortableTable >> sortAtRow: aRowIndex using: aSelector [ - header - do: [ :each | - (header at: aRowIndex) = each - ifFalse: [ each unsort ] ]. - rows := self rows - sorted: [ :cell :anotherCell | - [ (cell at: aRowIndex) perform: aSelector with: (anotherCell at: aRowIndex) ] - on: MessageNotUnderstood "If the element does not implements the comparators then I should not sort them." - do: [ true ] ] -] - -{ #category : #sorting } -MDLSortableTable >> sortDescendingAtRow: aRowIndex [ - self sortAtRow: aRowIndex using: #< -] - -{ #category : #accessing } -MDLSortableTable >> tableStyle [ - ^ tableStyle -] - -{ #category : #accessing } -MDLSortableTable >> tableStyle: anObject [ - tableStyle := anObject -] - -{ #category : #accessing } -MDLSortableTable >> title [ - ^ title -] - -{ #category : #accessing } -MDLSortableTable >> title: anObject [ - title := anObject -] - -{ #category : #sorting } -MDLSortableTable >> unsort [ - rows := unsortedRows -] +" +Sortable table, renders a table and adds the necessary behavior to navigate trough the table + + Instance Variables + elementsToShow: number of rows that will be rendered + header: a table with the table headers ( auto conversion from object ) + position: the index of the first row to render + rows: a table with all the rows + selectable: a boolean saying that the cells can be selected or not + ajaxOnCompleteHook: a String containing some JS code to be executed after we changed of page. By default it will update the MDL components to initialize the new ones. +" +Class { + #name : #MDLSortableTable, + #superclass : #WAComponent, + #instVars : [ + 'title', + 'header', + 'rows', + 'elementsToShow', + 'unsortedRows', + 'position', + 'rowsPerPagePossibilities', + 'selectable', + 'id', + 'ajaxOnCompleteHook', + 'tableStyle', + 'rowsCache' + ], + #category : #'Material-Design-Lite-Widgets-Table' +} + +{ #category : #accessing } +MDLSortableTable >> ajaxOnCompleteHook [ + "I am a hook to let the user add some javascript after the rendering of a new page. By default I will update the MDL components to initialize the new ones that might be in the table if needed." + + ^ ajaxOnCompleteHook ifNil: [ 'componentHandler.upgradeDom();' ] +] + +{ #category : #accessing } +MDLSortableTable >> ajaxOnCompleteHook: anObject [ + ajaxOnCompleteHook := anObject +] + +{ #category : #javascript } +MDLSortableTable >> ajaxUpdateScriptFrom: html [ + ^ html jQuery + script: [ :s | + s + << + ((html jQuery id: id) load + html: [ :ajaxHtml | self renderTableContentOn: ajaxHtml ]; + onComplete: self ajaxOnCompleteHook) ] +] + +{ #category : #accessing } +MDLSortableTable >> elementsToShow [ + ^ elementsToShow +] + +{ #category : #accessing } +MDLSortableTable >> elementsToShow: anObject [ + elementsToShow := anObject +] + +{ #category : #rendering } +MDLSortableTable >> ensureCurrentPageIsVisible [ + "In some case the elements to show can change. If we currently are in a page that does not exist anymore since the number of elements decreased, we should reset the position." + + self position > rowsCache size + ifTrue: [ self position: 1 ] +] + +{ #category : #accessing } +MDLSortableTable >> header [ + ^ header +] + +{ #category : #accessing } +MDLSortableTable >> header: aCollection [ + header := aCollection collect: [ :each | each asMDLSortableTableHeader ] +] + +{ #category : #rendering } +MDLSortableTable >> indexOfLastRowToShow [ + ^ rowsCache size min: position + elementsToShow - 1 +] + +{ #category : #initialization } +MDLSortableTable >> initialize [ + super initialize. + position := 1. + rows := #(). + header := #(). + unsortedRows := #(). + self rowsPerPagePossibilities: #(10 50 100). + selectable := false +] + +{ #category : #actions } +MDLSortableTable >> nextPosition [ + position + elementsToShow < rowsCache size + ifTrue: [ self position: position + elementsToShow ] +] + +{ #category : #accessing } +MDLSortableTable >> noPagination [ + self rowsPerPagePossibilities: {(Float infinity)} +] + +{ #category : #accessing } +MDLSortableTable >> position [ + ^ position +] + +{ #category : #accessing } +MDLSortableTable >> position: anObject [ + position := anObject +] + +{ #category : #actions } +MDLSortableTable >> previousPosition [ + self position: ((position - elementsToShow) max: 1) +] + +{ #category : #rendering } +MDLSortableTable >> renderButtonTriggering: aMethod withIcon: aSymbol disabled: isDisabled on: html [ + html mdlButton + bePush; + colored; + icon; + disabled: isDisabled; + onClick: [ html jQuery ajax + callback: [ self perform: aMethod ]; + onSuccess: (self ajaxUpdateScriptFrom: html) ] + if: isDisabled not; + with: [ html mdlIcon: aSymbol ] +] + +{ #category : #rendering } +MDLSortableTable >> renderContentOn: html [ + html mdlGrid + class: 'mdl-sorted-table'; + with: [ html mdlCard + shadow: 2; + class: 'mdl-sorted-table__wrapper'; + class: self tableStyle if: self tableStyle isNotNil; + id: (id := html nextId); + with: [ self renderTableContentOn: html ] ] +] + +{ #category : #rendering } +MDLSortableTable >> renderFooterPaginationOn: html [ + html mdlCardTextContainer + class: 'mdl-sorted-table__footer'; + with: [ + html div + mdlTypographyTextRight; + with: [ + html text: 'Rows per page: '. + self renderItemsByPageSelectionComponentOn: html. + self renderPagesInfoOn: html. + self + renderButtonTriggering: #previousPosition + withIcon: #keyboard_arrow_left + disabled: position = 1 + on: html. + self + renderButtonTriggering: #nextPosition + withIcon: #keyboard_arrow_right + disabled: position + elementsToShow > rowsCache size + on: html ] ] +] + +{ #category : #rendering } +MDLSortableTable >> renderHeaderOn: html [ + html + tableHead: [ html tableRow: [ header doWithIndex: [ :head :i | head renderContentOn: html forTable: self columnIndex: i ] ] ] +] + +{ #category : #accessing } +MDLSortableTable >> renderItemsByPageSelectionComponentOn: html [ + html + render: + (MDLSelectWidget new + labelBlock: #asString; + possibilities: rowsPerPagePossibilities; + callback: [ :o | self elementsToShow: o ]; + selectedObject: self elementsToShow; + sortBlock: [ :a :b | a asInteger <= b asInteger ]; + customizationBlock: [ :textField :renderer | textField onChange: (html jQuery ajax serializeThis onComplete: (self ajaxUpdateScriptFrom: html)) ]; + yourself) +] + +{ #category : #rendering } +MDLSortableTable >> renderPagesInfoOn: html [ + html + text: + (String + streamContents: [ :s | + s + print: position; + nextPutAll: ' - '; + print: self indexOfLastRowToShow; + nextPutAll: ' of '; + print: rowsCache size ]) +] + +{ #category : #rendering } +MDLSortableTable >> renderRowContentFor: cells on: html [ + header + doWithIndex: [ :headerCell :columnIndex | + | cell | + (headerCell tableCellOn: html) + with: + ((cell := cells at: columnIndex) isBlock + ifTrue: [ [ cell cull: html ] ] + ifFalse: [ cell ]) ] +] + +{ #category : #rendering } +MDLSortableTable >> renderRowsOn: html [ + ((position to: self indexOfLastRowToShow) collect: [ :rowIndex | rowsCache at: rowIndex ]) + do: [ :cells | html tableRow: [ self renderRowContentFor: cells on: html ] ] +] + +{ #category : #rendering } +MDLSortableTable >> renderTableContentOn: html [ + "We cache the rows because it is possible that the user give a block to execute." + + rowsCache := self rows. + self ensureCurrentPageIsVisible. + html div + class: 'mdl-sorted-table__content'; + with: [ self title ifNotNil: [ :t | html mdlCardTitleContainer: [ html mdlCardTitleText: t level: 2 ] ]. + (selectable + ifTrue: [ html mdlTable selectable ] + ifFalse: [ html mdlTable ]) + with: [ self renderHeaderOn: html. + self renderRowsOn: html ] ]. + self shouldDisplayPagination ifTrue: [ self renderFooterPaginationOn: html ] +] + +{ #category : #accessing } +MDLSortableTable >> rows [ + ^ rows value +] + +{ #category : #accessing } +MDLSortableTable >> rows: anObject [ + rows := anObject. + unsortedRows := anObject +] + +{ #category : #accessing } +MDLSortableTable >> rowsPerPagePossibilities [ + ^ rowsPerPagePossibilities +] + +{ #category : #accessing } +MDLSortableTable >> rowsPerPagePossibilities: aCollection [ + rowsPerPagePossibilities := aCollection. + aCollection ifNotEmpty: [ self elementsToShow: aCollection first ] +] + +{ #category : #accessing } +MDLSortableTable >> selectable [ + ^ selectable +] + +{ #category : #accessing } +MDLSortableTable >> selectable: anObject [ + selectable := anObject +] + +{ #category : #testing } +MDLSortableTable >> shouldDisplayPagination [ + ^ self rowsPerPagePossibilities min < rowsCache size +] + +{ #category : #sorting } +MDLSortableTable >> sortAscendingAtRow: aRowIndex [ + self sortAtRow: aRowIndex using: #> +] + +{ #category : #sorting } +MDLSortableTable >> sortAtRow: aRowIndex using: aSelector [ + header + do: [ :each | + (header at: aRowIndex) = each + ifFalse: [ each unsort ] ]. + rows := self rows + sorted: [ :cell :anotherCell | + [ (cell at: aRowIndex) perform: aSelector with: (anotherCell at: aRowIndex) ] + on: MessageNotUnderstood "If the element does not implements the comparators then I should not sort them." + do: [ true ] ] +] + +{ #category : #sorting } +MDLSortableTable >> sortDescendingAtRow: aRowIndex [ + self sortAtRow: aRowIndex using: #< +] + +{ #category : #accessing } +MDLSortableTable >> tableStyle [ + ^ tableStyle +] + +{ #category : #accessing } +MDLSortableTable >> tableStyle: anObject [ + tableStyle := anObject +] + +{ #category : #accessing } +MDLSortableTable >> title [ + ^ title +] + +{ #category : #accessing } +MDLSortableTable >> title: anObject [ + title := anObject +] + +{ #category : #sorting } +MDLSortableTable >> unsort [ + rows := unsortedRows +] diff --git a/src/Material-Design-Lite-Widgets/MDLSortableTableHeader.class.st b/src/Material-Design-Lite-Widgets/MDLSortableTableHeader.class.st index 735b63a4..fea7bd24 100644 --- a/src/Material-Design-Lite-Widgets/MDLSortableTableHeader.class.st +++ b/src/Material-Design-Lite-Widgets/MDLSortableTableHeader.class.st @@ -1,90 +1,90 @@ -Class { - #name : #MDLSortableTableHeader, - #superclass : #Object, - #instVars : [ - 'currentState', - 'unsortedState', - 'cells' - ], - #category : 'Material-Design-Lite-Widgets-Table' -} - -{ #category : #'instance creation' } -MDLSortableTableHeader class >> for: element [ - ^ self new cells: element -] - -{ #category : #converting } -MDLSortableTableHeader >> asMDLSortableTableHeader [ - ^ self -] - -{ #category : #accessing } -MDLSortableTableHeader >> cells [ - ^ cells -] - -{ #category : #accessing } -MDLSortableTableHeader >> cells: aCollection [ - cells := aCollection -] - -{ #category : #accessing } -MDLSortableTableHeader >> currentState [ - ^ currentState - ifNil: [ self unsort. - currentState ] -] - -{ #category : #accessing } -MDLSortableTableHeader >> currentState: anObject [ - currentState := anObject -] - -{ #category : #'state handling' } -MDLSortableTableHeader >> goToNextState [ - self currentState: self currentState nextState -] - -{ #category : #rendering } -MDLSortableTableHeader >> headingCellOn: html [ - ^ html mdlTableHeading - nonNumerical; - style: 'cursor: pointer;'; - yourself -] - -{ #category : #initialization } -MDLSortableTableHeader >> initialize [ - super initialize. - unsortedState := MDLSortableTableHeaderElementUnsorted new -] - -{ #category : #rendering } -MDLSortableTableHeader >> renderContentOn: aRenderer forTable: table columnIndex: i [ - self currentState - renderContentOn: aRenderer - forTable: table - columnIndex: i - header: self -] - -{ #category : #rendering } -MDLSortableTableHeader >> tableCellOn: html [ - ^ html mdlTableCell nonNumerical -] - -{ #category : #sorting } -MDLSortableTableHeader >> unsort [ - self currentState: self unsortedState -] - -{ #category : #accessing } -MDLSortableTableHeader >> unsortedState [ - ^ unsortedState -] - -{ #category : #accessing } -MDLSortableTableHeader >> unsortedState: anObject [ - unsortedState := anObject -] +Class { + #name : #MDLSortableTableHeader, + #superclass : #Object, + #instVars : [ + 'currentState', + 'unsortedState', + 'cells' + ], + #category : 'Material-Design-Lite-Widgets-Table' +} + +{ #category : #'instance creation' } +MDLSortableTableHeader class >> for: element [ + ^ self new cells: element +] + +{ #category : #converting } +MDLSortableTableHeader >> asMDLSortableTableHeader [ + ^ self +] + +{ #category : #accessing } +MDLSortableTableHeader >> cells [ + ^ cells +] + +{ #category : #accessing } +MDLSortableTableHeader >> cells: aCollection [ + cells := aCollection +] + +{ #category : #accessing } +MDLSortableTableHeader >> currentState [ + ^ currentState + ifNil: [ self unsort. + currentState ] +] + +{ #category : #accessing } +MDLSortableTableHeader >> currentState: anObject [ + currentState := anObject +] + +{ #category : #'state handling' } +MDLSortableTableHeader >> goToNextState [ + self currentState: self currentState nextState +] + +{ #category : #rendering } +MDLSortableTableHeader >> headingCellOn: html [ + ^ html mdlTableHeading + nonNumerical; + style: 'cursor: pointer;'; + yourself +] + +{ #category : #initialization } +MDLSortableTableHeader >> initialize [ + super initialize. + unsortedState := MDLSortableTableHeaderElementUnsorted new +] + +{ #category : #rendering } +MDLSortableTableHeader >> renderContentOn: aRenderer forTable: table columnIndex: i [ + self currentState + renderContentOn: aRenderer + forTable: table + columnIndex: i + header: self +] + +{ #category : #rendering } +MDLSortableTableHeader >> tableCellOn: html [ + ^ html mdlTableCell nonNumerical +] + +{ #category : #sorting } +MDLSortableTableHeader >> unsort [ + self currentState: self unsortedState +] + +{ #category : #accessing } +MDLSortableTableHeader >> unsortedState [ + ^ unsortedState +] + +{ #category : #accessing } +MDLSortableTableHeader >> unsortedState: anObject [ + unsortedState := anObject +] diff --git a/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderElementSortedAscending.class.st b/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderElementSortedAscending.class.st index 9b1ce380..8e1b16b8 100644 --- a/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderElementSortedAscending.class.st +++ b/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderElementSortedAscending.class.st @@ -1,22 +1,22 @@ -Class { - #name : #MDLSortableTableHeaderElementSortedAscending, - #superclass : #MDLSortableTableHeaderState, - #category : 'Material-Design-Lite-Widgets-Table' -} - -{ #category : #accessing } -MDLSortableTableHeaderElementSortedAscending class >> defaultNextState [ - ^ MDLSortableTableHeaderElementSortedDescending -] - -{ #category : #rendering } -MDLSortableTableHeaderElementSortedAscending >> renderContentOn: html forTable: table columnIndex: i header: header [ - (header headingCellOn: html) - sortedAscending; - onClick: - (html jQuery ajax - callback: [ table sortDescendingAtRow: i. - header goToNextState ]; - onSuccess: (table ajaxUpdateScriptFrom: html)); - with: header cells -] +Class { + #name : #MDLSortableTableHeaderElementSortedAscending, + #superclass : #MDLSortableTableHeaderState, + #category : 'Material-Design-Lite-Widgets-Table' +} + +{ #category : #accessing } +MDLSortableTableHeaderElementSortedAscending class >> defaultNextState [ + ^ MDLSortableTableHeaderElementSortedDescending +] + +{ #category : #rendering } +MDLSortableTableHeaderElementSortedAscending >> renderContentOn: html forTable: table columnIndex: i header: header [ + (header headingCellOn: html) + sortedAscending; + onClick: + (html jQuery ajax + callback: [ table sortDescendingAtRow: i. + header goToNextState ]; + onSuccess: (table ajaxUpdateScriptFrom: html)); + with: header cells +] diff --git a/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderElementSortedDescending.class.st b/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderElementSortedDescending.class.st index 8146d05d..7fe19f56 100644 --- a/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderElementSortedDescending.class.st +++ b/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderElementSortedDescending.class.st @@ -1,22 +1,22 @@ -Class { - #name : #MDLSortableTableHeaderElementSortedDescending, - #superclass : #MDLSortableTableHeaderState, - #category : 'Material-Design-Lite-Widgets-Table' -} - -{ #category : #accessing } -MDLSortableTableHeaderElementSortedDescending class >> defaultNextState [ - ^ MDLSortableTableHeaderElementUnsorted -] - -{ #category : #rendering } -MDLSortableTableHeaderElementSortedDescending >> renderContentOn: html forTable: table columnIndex: i header: header [ - (header headingCellOn: html) - sortedDescending; - onClick: - (html jQuery ajax - callback: [ table unsort. - header goToNextState ]; - onSuccess: (table ajaxUpdateScriptFrom: html)); - with: header cells -] +Class { + #name : #MDLSortableTableHeaderElementSortedDescending, + #superclass : #MDLSortableTableHeaderState, + #category : 'Material-Design-Lite-Widgets-Table' +} + +{ #category : #accessing } +MDLSortableTableHeaderElementSortedDescending class >> defaultNextState [ + ^ MDLSortableTableHeaderElementUnsorted +] + +{ #category : #rendering } +MDLSortableTableHeaderElementSortedDescending >> renderContentOn: html forTable: table columnIndex: i header: header [ + (header headingCellOn: html) + sortedDescending; + onClick: + (html jQuery ajax + callback: [ table unsort. + header goToNextState ]; + onSuccess: (table ajaxUpdateScriptFrom: html)); + with: header cells +] diff --git a/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderElementUnsorted.class.st b/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderElementUnsorted.class.st index d869b97f..544cdd73 100644 --- a/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderElementUnsorted.class.st +++ b/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderElementUnsorted.class.st @@ -1,21 +1,21 @@ -Class { - #name : #MDLSortableTableHeaderElementUnsorted, - #superclass : #MDLSortableTableHeaderState, - #category : 'Material-Design-Lite-Widgets-Table' -} - -{ #category : #accessing } -MDLSortableTableHeaderElementUnsorted class >> defaultNextState [ - ^ MDLSortableTableHeaderElementSortedAscending -] - -{ #category : #rendering } -MDLSortableTableHeaderElementUnsorted >> renderContentOn: html forTable: table columnIndex: i header: header [ - (header headingCellOn: html) - onClick: - (html jQuery ajax - callback: [ table sortAscendingAtRow: i. - header goToNextState ]; - onSuccess: (table ajaxUpdateScriptFrom: html)); - with: header cells -] +Class { + #name : #MDLSortableTableHeaderElementUnsorted, + #superclass : #MDLSortableTableHeaderState, + #category : 'Material-Design-Lite-Widgets-Table' +} + +{ #category : #accessing } +MDLSortableTableHeaderElementUnsorted class >> defaultNextState [ + ^ MDLSortableTableHeaderElementSortedAscending +] + +{ #category : #rendering } +MDLSortableTableHeaderElementUnsorted >> renderContentOn: html forTable: table columnIndex: i header: header [ + (header headingCellOn: html) + onClick: + (html jQuery ajax + callback: [ table sortAscendingAtRow: i. + header goToNextState ]; + onSuccess: (table ajaxUpdateScriptFrom: html)); + with: header cells +] diff --git a/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderNumeric.class.st b/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderNumeric.class.st index e9098bd2..f4e367a9 100644 --- a/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderNumeric.class.st +++ b/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderNumeric.class.st @@ -1,17 +1,17 @@ -Class { - #name : #MDLSortableTableHeaderNumeric, - #superclass : #MDLSortableTableHeader, - #category : 'Material-Design-Lite-Widgets-Table' -} - -{ #category : #rendering } -MDLSortableTableHeaderNumeric >> headingCellOn: html [ - ^ html mdlTableHeading - style: 'cursor: pointer;'; - yourself -] - -{ #category : #rendering } -MDLSortableTableHeaderNumeric >> tableCellOn: html [ - ^ html mdlTableCell -] +Class { + #name : #MDLSortableTableHeaderNumeric, + #superclass : #MDLSortableTableHeader, + #category : 'Material-Design-Lite-Widgets-Table' +} + +{ #category : #rendering } +MDLSortableTableHeaderNumeric >> headingCellOn: html [ + ^ html mdlTableHeading + style: 'cursor: pointer;'; + yourself +] + +{ #category : #rendering } +MDLSortableTableHeaderNumeric >> tableCellOn: html [ + ^ html mdlTableCell +] diff --git a/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderState.class.st b/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderState.class.st index e4245997..5f59c824 100644 --- a/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderState.class.st +++ b/src/Material-Design-Lite-Widgets/MDLSortableTableHeaderState.class.st @@ -1,43 +1,43 @@ -Class { - #name : #MDLSortableTableHeaderState, - #superclass : #Object, - #instVars : [ - 'nextState' - ], - #category : 'Material-Design-Lite-Widgets-Table' -} - -{ #category : #accessing } -MDLSortableTableHeaderState class >> defaultNextState [ - ^ self subclassResponsibility -] - -{ #category : #'instance creation' } -MDLSortableTableHeaderState class >> for: element [ - ^ self new element: element -] - -{ #category : #accessing } -MDLSortableTableHeaderState >> defaultNextState [ - ^ self class defaultNextState -] - -{ #category : #initialization } -MDLSortableTableHeaderState >> initializeNextState [ - self nextState: (self defaultNextState new nextState: (self defaultNextState defaultNextState new nextState: self)) -] - -{ #category : #accessing } -MDLSortableTableHeaderState >> nextState [ - ^ nextState ifNil: [ self initializeNextState. nextState ] -] - -{ #category : #accessing } -MDLSortableTableHeaderState >> nextState: anObject [ - nextState := anObject -] - -{ #category : #rendering } -MDLSortableTableHeaderState >> renderContentOn: html forTable: table columnIndex: i header: header [ - self subclassResponsibility -] +Class { + #name : #MDLSortableTableHeaderState, + #superclass : #Object, + #instVars : [ + 'nextState' + ], + #category : 'Material-Design-Lite-Widgets-Table' +} + +{ #category : #accessing } +MDLSortableTableHeaderState class >> defaultNextState [ + ^ self subclassResponsibility +] + +{ #category : #'instance creation' } +MDLSortableTableHeaderState class >> for: element [ + ^ self new element: element +] + +{ #category : #accessing } +MDLSortableTableHeaderState >> defaultNextState [ + ^ self class defaultNextState +] + +{ #category : #initialization } +MDLSortableTableHeaderState >> initializeNextState [ + self nextState: (self defaultNextState new nextState: (self defaultNextState defaultNextState new nextState: self)) +] + +{ #category : #accessing } +MDLSortableTableHeaderState >> nextState [ + ^ nextState ifNil: [ self initializeNextState. nextState ] +] + +{ #category : #accessing } +MDLSortableTableHeaderState >> nextState: anObject [ + nextState := anObject +] + +{ #category : #rendering } +MDLSortableTableHeaderState >> renderContentOn: html forTable: table columnIndex: i header: header [ + self subclassResponsibility +] diff --git a/src/Material-Design-Lite-Widgets/MDLStringColumnDescription.class.st b/src/Material-Design-Lite-Widgets/MDLStringColumnDescription.class.st index 3ec0d0bf..6ac6e50c 100644 --- a/src/Material-Design-Lite-Widgets/MDLStringColumnDescription.class.st +++ b/src/Material-Design-Lite-Widgets/MDLStringColumnDescription.class.st @@ -1,27 +1,27 @@ -" -I model a string column. - -My values are of kind string. Because of that, I align the title of the column on the left side. -" -Class { - #name : #MDLStringColumnDescription, - #superclass : #MDLTableColumnDescription, - #category : #'Material-Design-Lite-Widgets-Table' -} - -{ #category : #rendering } -MDLStringColumnDescription >> render: row on: html [ - html mdlTableCell - id: (self generateIdUsing: html); - class: 'mdl-table-widget__cell--string'; - nonNumerical; - with: (self evaluation value: row) -] - -{ #category : #rendering } -MDLStringColumnDescription >> renderHeadingOn: html [ - (super renderHeadingOn: html) - class: 'mdl-table-widget__cell--string'; - nonNumerical; - with: self title. -] +" +I model a string column. + +My values are of kind string. Because of that, I align the title of the column on the left side. +" +Class { + #name : #MDLStringColumnDescription, + #superclass : #MDLTableColumnDescription, + #category : #'Material-Design-Lite-Widgets-Table' +} + +{ #category : #rendering } +MDLStringColumnDescription >> render: row on: html [ + html mdlTableCell + id: (self generateIdUsing: html); + class: 'mdl-table-widget__cell--string'; + nonNumerical; + with: (self evaluation value: row) +] + +{ #category : #rendering } +MDLStringColumnDescription >> renderHeadingOn: html [ + (super renderHeadingOn: html) + class: 'mdl-table-widget__cell--string'; + nonNumerical; + with: self title. +] diff --git a/src/Material-Design-Lite-Widgets/MDLSubstringFilter.class.st b/src/Material-Design-Lite-Widgets/MDLSubstringFilter.class.st index 67d1da12..ae38a5f9 100644 --- a/src/Material-Design-Lite-Widgets/MDLSubstringFilter.class.st +++ b/src/Material-Design-Lite-Widgets/MDLSubstringFilter.class.st @@ -1,13 +1,13 @@ -" -I am a nested list filter keeping only elements whose name includes the pattern passed by the user. -" -Class { - #name : #MDLSubstringFilter, - #superclass : #MDLAbstractFilter, - #category : 'Material-Design-Lite-Widgets-List' -} - -{ #category : #accessing } -MDLSubstringFilter class >> formatedElement: aString matches: aPattern [ - ^ aString includesSubstring: aPattern -] +" +I am a nested list filter keeping only elements whose name includes the pattern passed by the user. +" +Class { + #name : #MDLSubstringFilter, + #superclass : #MDLAbstractFilter, + #category : 'Material-Design-Lite-Widgets-List' +} + +{ #category : #accessing } +MDLSubstringFilter class >> formatedElement: aString matches: aPattern [ + ^ aString includesSubstring: aPattern +] diff --git a/src/Material-Design-Lite-Widgets/MDLSwitchWidget.class.st b/src/Material-Design-Lite-Widgets/MDLSwitchWidget.class.st index 24c05a76..32fef9b6 100644 --- a/src/Material-Design-Lite-Widgets/MDLSwitchWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLSwitchWidget.class.st @@ -1,17 +1,17 @@ -Class { - #name : #MDLSwitchWidget, - #superclass : #MDLWidget, - #category : 'Material-Design-Lite-Widgets' -} - -{ #category : #rendering } -MDLSwitchWidget >> renderContentOn: html [ - html div - style: 'width: 28px;'; - with: [ - html mdlSwitchContainer for: (self id); with: [ - html mdlSwitch id: (self id); value: self value. - html mdlSwitchLabel - ] - ] -] +Class { + #name : #MDLSwitchWidget, + #superclass : #MDLWidget, + #category : 'Material-Design-Lite-Widgets' +} + +{ #category : #rendering } +MDLSwitchWidget >> renderContentOn: html [ + html div + style: 'width: 28px;'; + with: [ + html mdlSwitchContainer for: (self id); with: [ + html mdlSwitch id: (self id); value: self value. + html mdlSwitchLabel + ] + ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLTabWidget.class.st b/src/Material-Design-Lite-Widgets/MDLTabWidget.class.st index 9ae01028..48de9416 100644 --- a/src/Material-Design-Lite-Widgets/MDLTabWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLTabWidget.class.st @@ -1,62 +1,62 @@ -" -I represent a simple widget to use mdlTable -" -Class { - #name : #MDLTabWidget, - #superclass : #MDLHighLevelWidget, - #instVars : [ - 'tabs', - 'selectedTabIndex' - ], - #category : #'Material-Design-Lite-Widgets-Tab' -} - -{ #category : #adding } -MDLTabWidget >> addTabNamed: aString content: anObject [ - tabs at: aString put: anObject -] - -{ #category : #initialization } -MDLTabWidget >> initialize [ - super initialize. - tabs := OrderedDictionary new. - selectedTabIndex := 1 -] - -{ #category : #rendering } -MDLTabWidget >> renderContentOn: html [ - -self ensureId: html. - html mdlTabs - id: self id; - with: [ - | tabIds | - tabIds := Dictionary new. - html mdlTabBar: [ - tabs keysAndValuesDo: [ :label :tabContent | - html mdlTab - url: - '#' , (tabIds at: tabContent ifAbsentPut: [ html nextId ]); - - onClick: (html jQuery ajax callback: [ - self selectedTabIndex: (tabs indexOfKey: label) ]); - isActiveIf: (tabs indexOfKey: label) = self selectedTabIndex; - with: label ] ]. - tabs keysAndValuesDo: [ :label :tabContent | - html mdlTabsPanel - id: (tabIds at: tabContent); - isActiveIf: (tabs indexOfKey: label) = self selectedTabIndex; - with: tabContent ] ] -] - -{ #category : #accessing } -MDLTabWidget >> selectedTabIndex [ - - ^selectedTabIndex -] - -{ #category : #accessing } -MDLTabWidget >> selectedTabIndex: aNumber [ - - selectedTabIndex := aNumber -] +" +I represent a simple widget to use mdlTable +" +Class { + #name : #MDLTabWidget, + #superclass : #MDLHighLevelWidget, + #instVars : [ + 'tabs', + 'selectedTabIndex' + ], + #category : #'Material-Design-Lite-Widgets-Tab' +} + +{ #category : #adding } +MDLTabWidget >> addTabNamed: aString content: anObject [ + tabs at: aString put: anObject +] + +{ #category : #initialization } +MDLTabWidget >> initialize [ + super initialize. + tabs := OrderedDictionary new. + selectedTabIndex := 1 +] + +{ #category : #rendering } +MDLTabWidget >> renderContentOn: html [ + +self ensureId: html. + html mdlTabs + id: self id; + with: [ + | tabIds | + tabIds := Dictionary new. + html mdlTabBar: [ + tabs keysAndValuesDo: [ :label :tabContent | + html mdlTab + url: + '#' , (tabIds at: tabContent ifAbsentPut: [ html nextId ]); + + onClick: (html jQuery ajax callback: [ + self selectedTabIndex: (tabs indexOfKey: label) ]); + isActiveIf: (tabs indexOfKey: label) = self selectedTabIndex; + with: label ] ]. + tabs keysAndValuesDo: [ :label :tabContent | + html mdlTabsPanel + id: (tabIds at: tabContent); + isActiveIf: (tabs indexOfKey: label) = self selectedTabIndex; + with: tabContent ] ] +] + +{ #category : #accessing } +MDLTabWidget >> selectedTabIndex [ + + ^selectedTabIndex +] + +{ #category : #accessing } +MDLTabWidget >> selectedTabIndex: aNumber [ + + selectedTabIndex := aNumber +] diff --git a/src/Material-Design-Lite-Widgets/MDLTableColumnDescription.class.st b/src/Material-Design-Lite-Widgets/MDLTableColumnDescription.class.st index 9fa437ea..ee4b2aa2 100644 --- a/src/Material-Design-Lite-Widgets/MDLTableColumnDescription.class.st +++ b/src/Material-Design-Lite-Widgets/MDLTableColumnDescription.class.st @@ -1,76 +1,76 @@ -" -I am an abstract super class to model the description of a column for a MDLTableWidget. - -I hold my: -- #title which is the string to display as column name -- #idBlock which is the block that I use to generate an id. This block takes an argument which is the html canvas. -- #evaluation which is the block that I use to get the content of a cell concerning myself by providing it a row object. - -My subclasses model concrete column description check them for concrete examples. -" -Class { - #name : #MDLTableColumnDescription, - #superclass : #Object, - #instVars : [ - 'title', - 'evaluation', - 'idBlock' - ], - #category : #'Material-Design-Lite-Widgets-Table' -} - -{ #category : #accessing } -MDLTableColumnDescription >> evaluation [ - ^ evaluation -] - -{ #category : #accessing } -MDLTableColumnDescription >> evaluation: anObject [ - evaluation := anObject -] - -{ #category : #private } -MDLTableColumnDescription >> generateIdUsing: html [ - ^ self idBlock cull: html -] - -{ #category : #accessing } -MDLTableColumnDescription >> idBlock [ - ^ idBlock -] - -{ #category : #accessing } -MDLTableColumnDescription >> idBlock: anObject [ - idBlock := anObject -] - -{ #category : #initialization } -MDLTableColumnDescription >> initialize [ - super initialize. - self idBlock: [ :html | html nextId ] -] - -{ #category : #rendering } -MDLTableColumnDescription >> render: row on: html [ - self subclassResponsibility -] - -{ #category : #rendering } -MDLTableColumnDescription >> renderHeadingOn: html [ - | heading | - heading := html mdlTableHeading - id: (self generateIdUsing: html); - yourself. - - ^ heading -] - -{ #category : #accessing } -MDLTableColumnDescription >> title [ - ^ title -] - -{ #category : #accessing } -MDLTableColumnDescription >> title: anObject [ - title := anObject -] +" +I am an abstract super class to model the description of a column for a MDLTableWidget. + +I hold my: +- #title which is the string to display as column name +- #idBlock which is the block that I use to generate an id. This block takes an argument which is the html canvas. +- #evaluation which is the block that I use to get the content of a cell concerning myself by providing it a row object. + +My subclasses model concrete column description check them for concrete examples. +" +Class { + #name : #MDLTableColumnDescription, + #superclass : #Object, + #instVars : [ + 'title', + 'evaluation', + 'idBlock' + ], + #category : #'Material-Design-Lite-Widgets-Table' +} + +{ #category : #accessing } +MDLTableColumnDescription >> evaluation [ + ^ evaluation +] + +{ #category : #accessing } +MDLTableColumnDescription >> evaluation: anObject [ + evaluation := anObject +] + +{ #category : #private } +MDLTableColumnDescription >> generateIdUsing: html [ + ^ self idBlock cull: html +] + +{ #category : #accessing } +MDLTableColumnDescription >> idBlock [ + ^ idBlock +] + +{ #category : #accessing } +MDLTableColumnDescription >> idBlock: anObject [ + idBlock := anObject +] + +{ #category : #initialization } +MDLTableColumnDescription >> initialize [ + super initialize. + self idBlock: [ :html | html nextId ] +] + +{ #category : #rendering } +MDLTableColumnDescription >> render: row on: html [ + self subclassResponsibility +] + +{ #category : #rendering } +MDLTableColumnDescription >> renderHeadingOn: html [ + | heading | + heading := html mdlTableHeading + id: (self generateIdUsing: html); + yourself. + + ^ heading +] + +{ #category : #accessing } +MDLTableColumnDescription >> title [ + ^ title +] + +{ #category : #accessing } +MDLTableColumnDescription >> title: anObject [ + title := anObject +] diff --git a/src/Material-Design-Lite-Widgets/MDLTableWidget.class.st b/src/Material-Design-Lite-Widgets/MDLTableWidget.class.st index 4aaa0ea9..e98d4238 100644 --- a/src/Material-Design-Lite-Widgets/MDLTableWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLTableWidget.class.st @@ -1,124 +1,124 @@ -" -I am table widget which aims to provide a high-level API to generate MDL tables. - -I work by providing myself a #collection which just needs to be iterable (i.e. understand #do:) and a list of column descriptions. - -I provide a nice API to add colum descriptions (see my 'adding' protocol). -" -Class { - #name : #MDLTableWidget, - #superclass : #WAComponent, - #instVars : [ - 'columnDescriptions', - 'collection' - ], - #category : #'Material-Design-Lite-Widgets-Table' -} - -{ #category : #adding } -MDLTableWidget >> addAjaxButtonColumnNamed: aString iconName: iconName onClick: onClickBlock [ - self addAjaxButtonColumnNamed: aString iconName: iconName onClick: onClickBlock tooltip: nil -] - -{ #category : #adding } -MDLTableWidget >> addAjaxButtonColumnNamed: aString iconName: iconName onClick: onClickBlock tooltip: tooltip [ - self addColumn: (MDLAjaxButtonColumnDescription new - title: aString; - iconName: iconName; - onClickBlock: onClickBlock; - tooltip: tooltip; - yourself) -] - -{ #category : #adding } -MDLTableWidget >> addAjaxButtonColumnWithIconName: iconName onClick: onClickBlock tooltip: tooltip [ - self addAjaxButtonColumnNamed: '' iconName: iconName onClick: onClickBlock tooltip: tooltip -] - -{ #category : #adding } -MDLTableWidget >> addButtonColumnNamed: aString iconName: iconName onClick: onClickBlock tooltip: tooltip [ - self addColumn: (MDLButtonColumnDescription new - title: aString; - iconName: iconName; - onClickBlock: onClickBlock; - tooltip: tooltip; - yourself) -] - -{ #category : #adding } -MDLTableWidget >> addButtonColumnWithIconName: iconName onClick: onClickBlock tooltip: tooltip [ - self addButtonColumnNamed: '' iconName: iconName onClick: onClickBlock tooltip: tooltip -] - -{ #category : #adding } -MDLTableWidget >> addColumn: aColumnDescription [ - columnDescriptions add: aColumnDescription -] - -{ #category : #adding } -MDLTableWidget >> addNumericColumnNamed: aString evaluated: aBlock [ - self addColumn: (MDLNumericColumnDescription new - title: aString; - evaluation: aBlock; - yourself) -] - -{ #category : #adding } -MDLTableWidget >> addStringColumnNamed: aString evaluated: aBlock [ - self addColumn: (MDLStringColumnDescription new - title: aString; - evaluation: aBlock; - yourself) -] - -{ #category : #accessing } -MDLTableWidget >> collection [ - ^ collection -] - -{ #category : #accessing } -MDLTableWidget >> collection: anObject [ - collection := anObject -] - -{ #category : #accessing } -MDLTableWidget >> columnDescriptions [ - ^ columnDescriptions -] - -{ #category : #initialization } -MDLTableWidget >> initialize [ - super initialize. - columnDescriptions := OrderedCollection new. - collection := #() -] - -{ #category : #rendering } -MDLTableWidget >> renderContentOn: html [ - html mdlTable - class: 'mdl-table-widget'; - with: [ - self renderTableHeadOn: html. - self renderTableBodyOn: html ] -] - -{ #category : #rendering } -MDLTableWidget >> renderTableBodyOn: html [ - html tableBody - class: 'mdl-table-widget__body'; - with: [ - self collection do: [ :row | - html tableRow: [ - self columnDescriptions do: [ :columnDescription | - columnDescription render: row on: html ] ] ] ] -] - -{ #category : #rendering } -MDLTableWidget >> renderTableHeadOn: html [ - html tableHead - class: 'mdl-table-widget__head'; - with: [ - html tableRow: [ - self columnDescriptions do: [ :column | - column renderHeadingOn: html ] ] ] -] +" +I am table widget which aims to provide a high-level API to generate MDL tables. + +I work by providing myself a #collection which just needs to be iterable (i.e. understand #do:) and a list of column descriptions. + +I provide a nice API to add colum descriptions (see my 'adding' protocol). +" +Class { + #name : #MDLTableWidget, + #superclass : #WAComponent, + #instVars : [ + 'columnDescriptions', + 'collection' + ], + #category : #'Material-Design-Lite-Widgets-Table' +} + +{ #category : #adding } +MDLTableWidget >> addAjaxButtonColumnNamed: aString iconName: iconName onClick: onClickBlock [ + self addAjaxButtonColumnNamed: aString iconName: iconName onClick: onClickBlock tooltip: nil +] + +{ #category : #adding } +MDLTableWidget >> addAjaxButtonColumnNamed: aString iconName: iconName onClick: onClickBlock tooltip: tooltip [ + self addColumn: (MDLAjaxButtonColumnDescription new + title: aString; + iconName: iconName; + onClickBlock: onClickBlock; + tooltip: tooltip; + yourself) +] + +{ #category : #adding } +MDLTableWidget >> addAjaxButtonColumnWithIconName: iconName onClick: onClickBlock tooltip: tooltip [ + self addAjaxButtonColumnNamed: '' iconName: iconName onClick: onClickBlock tooltip: tooltip +] + +{ #category : #adding } +MDLTableWidget >> addButtonColumnNamed: aString iconName: iconName onClick: onClickBlock tooltip: tooltip [ + self addColumn: (MDLButtonColumnDescription new + title: aString; + iconName: iconName; + onClickBlock: onClickBlock; + tooltip: tooltip; + yourself) +] + +{ #category : #adding } +MDLTableWidget >> addButtonColumnWithIconName: iconName onClick: onClickBlock tooltip: tooltip [ + self addButtonColumnNamed: '' iconName: iconName onClick: onClickBlock tooltip: tooltip +] + +{ #category : #adding } +MDLTableWidget >> addColumn: aColumnDescription [ + columnDescriptions add: aColumnDescription +] + +{ #category : #adding } +MDLTableWidget >> addNumericColumnNamed: aString evaluated: aBlock [ + self addColumn: (MDLNumericColumnDescription new + title: aString; + evaluation: aBlock; + yourself) +] + +{ #category : #adding } +MDLTableWidget >> addStringColumnNamed: aString evaluated: aBlock [ + self addColumn: (MDLStringColumnDescription new + title: aString; + evaluation: aBlock; + yourself) +] + +{ #category : #accessing } +MDLTableWidget >> collection [ + ^ collection +] + +{ #category : #accessing } +MDLTableWidget >> collection: anObject [ + collection := anObject +] + +{ #category : #accessing } +MDLTableWidget >> columnDescriptions [ + ^ columnDescriptions +] + +{ #category : #initialization } +MDLTableWidget >> initialize [ + super initialize. + columnDescriptions := OrderedCollection new. + collection := #() +] + +{ #category : #rendering } +MDLTableWidget >> renderContentOn: html [ + html mdlTable + class: 'mdl-table-widget'; + with: [ + self renderTableHeadOn: html. + self renderTableBodyOn: html ] +] + +{ #category : #rendering } +MDLTableWidget >> renderTableBodyOn: html [ + html tableBody + class: 'mdl-table-widget__body'; + with: [ + self collection do: [ :row | + html tableRow: [ + self columnDescriptions do: [ :columnDescription | + columnDescription render: row on: html ] ] ] ] +] + +{ #category : #rendering } +MDLTableWidget >> renderTableHeadOn: html [ + html tableHead + class: 'mdl-table-widget__head'; + with: [ + html tableRow: [ + self columnDescriptions do: [ :column | + column renderHeadingOn: html ] ] ] +] diff --git a/src/Material-Design-Lite-Widgets/MDLTextAreaWidget.class.st b/src/Material-Design-Lite-Widgets/MDLTextAreaWidget.class.st index c36932a9..8a1efc35 100644 --- a/src/Material-Design-Lite-Widgets/MDLTextAreaWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLTextAreaWidget.class.st @@ -1,25 +1,25 @@ -" -I represent a text area with material design style. -You can use all methods of MDLTextFieldWidget on me. -" -Class { - #name : #MDLTextAreaWidget, - #superclass : #MDLTextFieldWidget, - #category : #'Material-Design-Lite-Widgets-Form' -} - -{ #category : #options } -MDLTextAreaWidget >> columns: aNumber [ - self propertiesAt: #columns: put: (Array with: aNumber) -] - -{ #category : #initialization } -MDLTextAreaWidget >> initialize [ - super initialize. - brush := MDLTextArea new -] - -{ #category : #options } -MDLTextAreaWidget >> rows: aNumber [ - self propertiesAt: #rows: put: (Array with: aNumber) -] +" +I represent a text area with material design style. +You can use all methods of MDLTextFieldWidget on me. +" +Class { + #name : #MDLTextAreaWidget, + #superclass : #MDLTextFieldWidget, + #category : #'Material-Design-Lite-Widgets-Form' +} + +{ #category : #options } +MDLTextAreaWidget >> columns: aNumber [ + self propertiesAt: #columns: put: (Array with: aNumber) +] + +{ #category : #initialization } +MDLTextAreaWidget >> initialize [ + super initialize. + brush := MDLTextArea new +] + +{ #category : #options } +MDLTextAreaWidget >> rows: aNumber [ + self propertiesAt: #rows: put: (Array with: aNumber) +] diff --git a/src/Material-Design-Lite-Widgets/MDLTextFieldWidget.class.st b/src/Material-Design-Lite-Widgets/MDLTextFieldWidget.class.st index 33cc4b4b..d492734f 100644 --- a/src/Material-Design-Lite-Widgets/MDLTextFieldWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLTextFieldWidget.class.st @@ -1,189 +1,189 @@ -" -I represent a text input field widget -" -Class { - #name : #MDLTextFieldWidget, - #superclass : #MDLHighLevelWidget, - #instVars : [ - 'label', - 'brush', - 'isExpandable', - 'isFloatingLabel', - 'patternErrorMessage', - 'errorMessage' - ], - #category : 'Material-Design-Lite-Widgets-Form' -} - -{ #category : #'instance creation' } -MDLTextFieldWidget class >> labeled: aString callback: aBlock [ - ^ self labeled: aString callback: aBlock floatingLabel: false -] - -{ #category : #'instance creation' } -MDLTextFieldWidget class >> labeled: aString callback: aBlock floatingLabel: aBoolean [ - ^ self - labeled: aString - callback: aBlock - floatingLabel: aBoolean - expandable: false -] - -{ #category : #'instance creation' } -MDLTextFieldWidget class >> labeled: aString callback: aBlock floatingLabel: aBoolean expandable: aBoolean2 [ - ^ self new - label: aString; - callback: aBlock; - floatingLabelIf: aBoolean; - expandableIf: aBoolean2; - yourself -] - -{ #category : #options } -MDLTextFieldWidget >> beExpandable [ - isExpandable := true -] - -{ #category : #options } -MDLTextFieldWidget >> beFloatingLabel [ - isFloatingLabel := true -] - -{ #category : #options } -MDLTextFieldWidget >> callback: aBlock [ - self propertiesAt: #callback: put: (Array with: aBlock) -] - -{ #category : #accessing } -MDLTextFieldWidget >> errorMessage [ - ^ errorMessage ifNil: [ errorMessage := '' ] -] - -{ #category : #accessing } -MDLTextFieldWidget >> errorMessage: aString [ - errorMessage := aString -] - -{ #category : #accessing } -MDLTextFieldWidget >> errorMessage: aString if: aBoolean [ - aBoolean - ifTrue: [ errorMessage := aString ] -] - -{ #category : #options } -MDLTextFieldWidget >> expandableIf: aBoolean [ - aBoolean - ifTrue: [ self beExpandable ] -] - -{ #category : #options } -MDLTextFieldWidget >> floatingLabelIf: aBoolean [ - aBoolean - ifTrue: [ self beFloatingLabel ] -] - -{ #category : #initialization } -MDLTextFieldWidget >> initialize [ - super initialize. - brush := MDLTextFieldInput new. - isExpandable := false. - isFloatingLabel := false. - patternErrorMessage := '' -] - -{ #category : #accessing } -MDLTextFieldWidget >> label [ - ^ label -] - -{ #category : #accessing } -MDLTextFieldWidget >> label: aString [ - label := aString -] - -{ #category : #options } -MDLTextFieldWidget >> on: aSymbol of: anObject [ - self propertiesAt: #on:of: put: (Array with: aSymbol with: anObject) -] - -{ #category : #options } -MDLTextFieldWidget >> onChange: anObject [ - self propertiesAt: #onChange: put: (Array with: anObject) -] - -{ #category : #options } -MDLTextFieldWidget >> onEnter: anObject [ - self propertiesAt: #onEnter: put: (Array with: anObject) -] - -{ #category : #options } -MDLTextFieldWidget >> onKeyUp: anObject [ - self propertiesAt: #onKeyUp: put: (Array with: anObject) -] - -{ #category : #options } -MDLTextFieldWidget >> onSubmit: anObject [ - self propertiesAt: #onSubmit: put: (Array with: anObject) -] - -{ #category : #options } -MDLTextFieldWidget >> pattern: anObject [ - self propertiesAt: #pattern: put: (Array with: anObject) -] - -{ #category : #options } -MDLTextFieldWidget >> pattern: aPattern errorMessage: aString [ - "patternsDictionary at: anObject put: aString" - - self pattern: aPattern. - patternErrorMessage := aString -] - -{ #category : #options } -MDLTextFieldWidget >> readonly: aBoolean [ - self propertiesAt: #readonly: put: (Array with: aBoolean) -] - -{ #category : #rendering } -MDLTextFieldWidget >> renderContentOn: html [ - | inputId | - self id ifNotNil: [ :aString | inputId := aString ] ifNil: [ inputId := html nextId ]. - html mdlTextFieldContainer - class: (self properties at: #class: ifAbsent: [ '' ]); - beFloatingLabelIf: isFloatingLabel; - beExpandableIf: isExpandable; - with: [ - label - ifNotNil: [ - html mdlTextFieldLabel - for: inputId; - with: label ]. - html - brush: - (brush - id: inputId; - yourself). - self addPropertiesToBrush: brush. - patternErrorMessage ifNotEmpty: [ html mdlTextFieldError: patternErrorMessage ]. - self errorMessage ifNotEmpty: [ :message | html mdlTextFieldError: message ] ] -] - -{ #category : #options } -MDLTextFieldWidget >> required [ - self propertiesAt: #required put: Array new -] - -{ #category : #options } -MDLTextFieldWidget >> size: anObject [ - self propertiesAt: #size: put: (Array with: anObject) -] - -{ #category : #options } -MDLTextFieldWidget >> type: anObject [ - self propertiesAt: #type: put: (Array with: anObject) -] - -{ #category : #options } -MDLTextFieldWidget >> value: anObject [ - self propertiesAt: #value: put: (Array with: anObject) -] +" +I represent a text input field widget +" +Class { + #name : #MDLTextFieldWidget, + #superclass : #MDLHighLevelWidget, + #instVars : [ + 'label', + 'brush', + 'isExpandable', + 'isFloatingLabel', + 'patternErrorMessage', + 'errorMessage' + ], + #category : 'Material-Design-Lite-Widgets-Form' +} + +{ #category : #'instance creation' } +MDLTextFieldWidget class >> labeled: aString callback: aBlock [ + ^ self labeled: aString callback: aBlock floatingLabel: false +] + +{ #category : #'instance creation' } +MDLTextFieldWidget class >> labeled: aString callback: aBlock floatingLabel: aBoolean [ + ^ self + labeled: aString + callback: aBlock + floatingLabel: aBoolean + expandable: false +] + +{ #category : #'instance creation' } +MDLTextFieldWidget class >> labeled: aString callback: aBlock floatingLabel: aBoolean expandable: aBoolean2 [ + ^ self new + label: aString; + callback: aBlock; + floatingLabelIf: aBoolean; + expandableIf: aBoolean2; + yourself +] + +{ #category : #options } +MDLTextFieldWidget >> beExpandable [ + isExpandable := true +] + +{ #category : #options } +MDLTextFieldWidget >> beFloatingLabel [ + isFloatingLabel := true +] + +{ #category : #options } +MDLTextFieldWidget >> callback: aBlock [ + self propertiesAt: #callback: put: (Array with: aBlock) +] + +{ #category : #accessing } +MDLTextFieldWidget >> errorMessage [ + ^ errorMessage ifNil: [ errorMessage := '' ] +] + +{ #category : #accessing } +MDLTextFieldWidget >> errorMessage: aString [ + errorMessage := aString +] + +{ #category : #accessing } +MDLTextFieldWidget >> errorMessage: aString if: aBoolean [ + aBoolean + ifTrue: [ errorMessage := aString ] +] + +{ #category : #options } +MDLTextFieldWidget >> expandableIf: aBoolean [ + aBoolean + ifTrue: [ self beExpandable ] +] + +{ #category : #options } +MDLTextFieldWidget >> floatingLabelIf: aBoolean [ + aBoolean + ifTrue: [ self beFloatingLabel ] +] + +{ #category : #initialization } +MDLTextFieldWidget >> initialize [ + super initialize. + brush := MDLTextFieldInput new. + isExpandable := false. + isFloatingLabel := false. + patternErrorMessage := '' +] + +{ #category : #accessing } +MDLTextFieldWidget >> label [ + ^ label +] + +{ #category : #accessing } +MDLTextFieldWidget >> label: aString [ + label := aString +] + +{ #category : #options } +MDLTextFieldWidget >> on: aSymbol of: anObject [ + self propertiesAt: #on:of: put: (Array with: aSymbol with: anObject) +] + +{ #category : #options } +MDLTextFieldWidget >> onChange: anObject [ + self propertiesAt: #onChange: put: (Array with: anObject) +] + +{ #category : #options } +MDLTextFieldWidget >> onEnter: anObject [ + self propertiesAt: #onEnter: put: (Array with: anObject) +] + +{ #category : #options } +MDLTextFieldWidget >> onKeyUp: anObject [ + self propertiesAt: #onKeyUp: put: (Array with: anObject) +] + +{ #category : #options } +MDLTextFieldWidget >> onSubmit: anObject [ + self propertiesAt: #onSubmit: put: (Array with: anObject) +] + +{ #category : #options } +MDLTextFieldWidget >> pattern: anObject [ + self propertiesAt: #pattern: put: (Array with: anObject) +] + +{ #category : #options } +MDLTextFieldWidget >> pattern: aPattern errorMessage: aString [ + "patternsDictionary at: anObject put: aString" + + self pattern: aPattern. + patternErrorMessage := aString +] + +{ #category : #options } +MDLTextFieldWidget >> readonly: aBoolean [ + self propertiesAt: #readonly: put: (Array with: aBoolean) +] + +{ #category : #rendering } +MDLTextFieldWidget >> renderContentOn: html [ + | inputId | + self id ifNotNil: [ :aString | inputId := aString ] ifNil: [ inputId := html nextId ]. + html mdlTextFieldContainer + class: (self properties at: #class: ifAbsent: [ '' ]); + beFloatingLabelIf: isFloatingLabel; + beExpandableIf: isExpandable; + with: [ + label + ifNotNil: [ + html mdlTextFieldLabel + for: inputId; + with: label ]. + html + brush: + (brush + id: inputId; + yourself). + self addPropertiesToBrush: brush. + patternErrorMessage ifNotEmpty: [ html mdlTextFieldError: patternErrorMessage ]. + self errorMessage ifNotEmpty: [ :message | html mdlTextFieldError: message ] ] +] + +{ #category : #options } +MDLTextFieldWidget >> required [ + self propertiesAt: #required put: Array new +] + +{ #category : #options } +MDLTextFieldWidget >> size: anObject [ + self propertiesAt: #size: put: (Array with: anObject) +] + +{ #category : #options } +MDLTextFieldWidget >> type: anObject [ + self propertiesAt: #type: put: (Array with: anObject) +] + +{ #category : #options } +MDLTextFieldWidget >> value: anObject [ + self propertiesAt: #value: put: (Array with: anObject) +] diff --git a/src/Material-Design-Lite-Widgets/MDLWidget.class.st b/src/Material-Design-Lite-Widgets/MDLWidget.class.st index 038db440..4e1bf978 100644 --- a/src/Material-Design-Lite-Widgets/MDLWidget.class.st +++ b/src/Material-Design-Lite-Widgets/MDLWidget.class.st @@ -1,55 +1,55 @@ -Class { - #name : #MDLWidget, - #superclass : #WAComponent, - #instVars : [ - 'id', - 'value' - ], - #category : 'Material-Design-Lite-Widgets' -} - -{ #category : #initialize } -MDLWidget class >> id: aStringID [ - ^self id: aStringID value: true -] - -{ #category : #initialize } -MDLWidget class >> id: aStringID value: aBooleanValue [ - ^self new - id: aStringID; - value: aBooleanValue; - yourself -] - -{ #category : #id } -MDLWidget >> ensureId: html [ - self id ifNil: [ self id: html nextId ] -] - -{ #category : #accessing } -MDLWidget >> id [ - ^ id -] - -{ #category : #accessing } -MDLWidget >> id: anObject [ - id := anObject -] - -{ #category : #actions } -MDLWidget >> restoreFromSnapshot: anObject [ - | oldId | - oldId := self id. - super restoreFromSnapshot: anObject. - self id: oldId -] - -{ #category : #accessing } -MDLWidget >> value [ - ^ value -] - -{ #category : #accessing } -MDLWidget >> value: anObject [ - value := anObject -] +Class { + #name : #MDLWidget, + #superclass : #WAComponent, + #instVars : [ + 'id', + 'value' + ], + #category : 'Material-Design-Lite-Widgets' +} + +{ #category : #initialize } +MDLWidget class >> id: aStringID [ + ^self id: aStringID value: true +] + +{ #category : #initialize } +MDLWidget class >> id: aStringID value: aBooleanValue [ + ^self new + id: aStringID; + value: aBooleanValue; + yourself +] + +{ #category : #id } +MDLWidget >> ensureId: html [ + self id ifNil: [ self id: html nextId ] +] + +{ #category : #accessing } +MDLWidget >> id [ + ^ id +] + +{ #category : #accessing } +MDLWidget >> id: anObject [ + id := anObject +] + +{ #category : #actions } +MDLWidget >> restoreFromSnapshot: anObject [ + | oldId | + oldId := self id. + super restoreFromSnapshot: anObject. + self id: oldId +] + +{ #category : #accessing } +MDLWidget >> value [ + ^ value +] + +{ #category : #accessing } +MDLWidget >> value: anObject [ + value := anObject +] diff --git a/src/Material-Design-Lite-Widgets/ManifestMaterialDesignLiteWidgets.class.st b/src/Material-Design-Lite-Widgets/ManifestMaterialDesignLiteWidgets.class.st index b0ddb9a5..3d423394 100644 --- a/src/Material-Design-Lite-Widgets/ManifestMaterialDesignLiteWidgets.class.st +++ b/src/Material-Design-Lite-Widgets/ManifestMaterialDesignLiteWidgets.class.st @@ -1,35 +1,35 @@ -" -I store metadata for this package. These meta data are used by other tools such as the SmalllintManifestChecker and the critics Browser -" -Class { - #name : #ManifestMaterialDesignLiteWidgets, - #superclass : #PackageManifest, - #category : 'Material-Design-Lite-Widgets-Manifest' -} - -{ #category : #'meta-data' } -ManifestMaterialDesignLiteWidgets class >> description [ ^ 'Material Design Lite for Seaside (MDL) is a library of components for web developers based on Google''s Material Design Philosophy: "A visual language for our users that synthesizes the classic principles of good design with the innovation and possibility of technology and science." Understanding the goals and principles of Material Design is critical to the proper use of the Material Design Lite components. If you have not yet read the Material Design Introduction you should do so before attempting to use the components. (See https://material.io/guidelines/material-design/) - -Github: https://github.com/DuneSt/MaterialDesignLite - -Demo: https://mdl.ferlicot.fr/ - -The second part of Material Design Lite for Seaside is the Widgets. Widgets are Seaside components with behaviour at the difference of MDL components. They respect Material Design rules and provide to the developers predefined behaviour. - -An exemple of widget is the nested list already containing features such as dynamic loading of elements, research, sorting...' -] - -{ #category : #'code-critics' } -ManifestMaterialDesignLiteWidgets class >> ruleGRAnsiConditionalsRuleV1FalsePositive [ - ^ #(#(#(#RGMethodDefinition #(#MDLTextFieldWidget #renderContentOn: #false)) #'2016-07-06T16:57:57.793+02:00') ) -] - -{ #category : #'code-critics' } -ManifestMaterialDesignLiteWidgets class >> ruleRBSendsDifferentSuperRuleV1FalsePositive [ - ^ #(#(#(#RGMethodDefinition #(#MDLLoginDialogWidget #renderLoginDialogOn: #false)) #'2016-07-11T14:50:20.68+02:00') ) -] - -{ #category : #'code-critics' } -ManifestMaterialDesignLiteWidgets class >> ruleRBTempsReadBeforeWrittenRuleV1FalsePositive [ - ^ #(#(#(#RGMethodDefinition #(#MDLTextFieldWidget #renderContentOn: #false)) #'2016-07-11T15:47:20.1+02:00') ) -] +" +I store metadata for this package. These meta data are used by other tools such as the SmalllintManifestChecker and the critics Browser +" +Class { + #name : #ManifestMaterialDesignLiteWidgets, + #superclass : #PackageManifest, + #category : 'Material-Design-Lite-Widgets-Manifest' +} + +{ #category : #'meta-data' } +ManifestMaterialDesignLiteWidgets class >> description [ ^ 'Material Design Lite for Seaside (MDL) is a library of components for web developers based on Google''s Material Design Philosophy: "A visual language for our users that synthesizes the classic principles of good design with the innovation and possibility of technology and science." Understanding the goals and principles of Material Design is critical to the proper use of the Material Design Lite components. If you have not yet read the Material Design Introduction you should do so before attempting to use the components. (See https://material.io/guidelines/material-design/) + +Github: https://github.com/DuneSt/MaterialDesignLite + +Demo: https://mdl.ferlicot.fr/ + +The second part of Material Design Lite for Seaside is the Widgets. Widgets are Seaside components with behaviour at the difference of MDL components. They respect Material Design rules and provide to the developers predefined behaviour. + +An exemple of widget is the nested list already containing features such as dynamic loading of elements, research, sorting...' +] + +{ #category : #'code-critics' } +ManifestMaterialDesignLiteWidgets class >> ruleGRAnsiConditionalsRuleV1FalsePositive [ + ^ #(#(#(#RGMethodDefinition #(#MDLTextFieldWidget #renderContentOn: #false)) #'2016-07-06T16:57:57.793+02:00') ) +] + +{ #category : #'code-critics' } +ManifestMaterialDesignLiteWidgets class >> ruleRBSendsDifferentSuperRuleV1FalsePositive [ + ^ #(#(#(#RGMethodDefinition #(#MDLLoginDialogWidget #renderLoginDialogOn: #false)) #'2016-07-11T14:50:20.68+02:00') ) +] + +{ #category : #'code-critics' } +ManifestMaterialDesignLiteWidgets class >> ruleRBTempsReadBeforeWrittenRuleV1FalsePositive [ + ^ #(#(#(#RGMethodDefinition #(#MDLTextFieldWidget #renderContentOn: #false)) #'2016-07-11T15:47:20.1+02:00') ) +] diff --git a/src/Material-Design-Lite-Widgets/Object.extension.st b/src/Material-Design-Lite-Widgets/Object.extension.st index c2cbdf14..b8d12fd2 100644 --- a/src/Material-Design-Lite-Widgets/Object.extension.st +++ b/src/Material-Design-Lite-Widgets/Object.extension.st @@ -1,11 +1,11 @@ -Extension { #name : #Object } - -{ #category : #'*Material-Design-Lite-Widgets' } -Object >> asMDLSortableTableHeader [ - ^ MDLSortableTableHeader for: self -] - -{ #category : #'*Material-Design-Lite-Widgets' } -Object >> asNumericMDLSortableTable [ - ^ MDLSortableTableHeaderNumeric for: self -] +Extension { #name : #Object } + +{ #category : #'*Material-Design-Lite-Widgets' } +Object >> asMDLSortableTableHeader [ + ^ MDLSortableTableHeader for: self +] + +{ #category : #'*Material-Design-Lite-Widgets' } +Object >> asNumericMDLSortableTable [ + ^ MDLSortableTableHeaderNumeric for: self +] diff --git a/src/Material-Design-Lite-Widgets/SequenceableCollection.extension.st b/src/Material-Design-Lite-Widgets/SequenceableCollection.extension.st index 3f5c8a47..8c39885a 100644 --- a/src/Material-Design-Lite-Widgets/SequenceableCollection.extension.st +++ b/src/Material-Design-Lite-Widgets/SequenceableCollection.extension.st @@ -1,13 +1,13 @@ -Extension { #name : #SequenceableCollection } - -{ #category : #'*Material-Design-Lite-Widgets' } -SequenceableCollection >> groupsOf: n [ - | grouped index | - grouped := self species new. - index := 1. - [ index > self size ] - whileFalse: [ grouped - add: (self copyFrom: index to: (index + n - 1 min: self size)) asArray. - index := index + n ]. - ^ grouped -] +Extension { #name : #SequenceableCollection } + +{ #category : #'*Material-Design-Lite-Widgets' } +SequenceableCollection >> groupsOf: n [ + | grouped index | + grouped := self species new. + index := 1. + [ index > self size ] + whileFalse: [ grouped + add: (self copyFrom: index to: (index + n - 1 min: self size)) asArray. + index := index + n ]. + ^ grouped +] diff --git a/src/Material-Design-Lite-Widgets/Symbol.extension.st b/src/Material-Design-Lite-Widgets/Symbol.extension.st index 10463929..0d18fe5f 100644 --- a/src/Material-Design-Lite-Widgets/Symbol.extension.st +++ b/src/Material-Design-Lite-Widgets/Symbol.extension.st @@ -1,11 +1,11 @@ -Extension { #name : #Symbol } - -{ #category : #'*Material-Design-Lite-Widgets' } -Symbol >> argumentCount [ - ^ 1 -] - -{ #category : #'*Material-Design-Lite-Widgets' } -Symbol >> mdlCull: anObject cull: anotherObject [ - ^ self cull: anObject -] +Extension { #name : #Symbol } + +{ #category : #'*Material-Design-Lite-Widgets' } +Symbol >> argumentCount [ + ^ 1 +] + +{ #category : #'*Material-Design-Lite-Widgets' } +Symbol >> mdlCull: anObject cull: anotherObject [ + ^ self cull: anObject +] diff --git a/src/Material-Design-Lite-Widgets/package.st b/src/Material-Design-Lite-Widgets/package.st index a4313d2d..9e430518 100644 --- a/src/Material-Design-Lite-Widgets/package.st +++ b/src/Material-Design-Lite-Widgets/package.st @@ -1 +1 @@ -Package { #name : #'Material-Design-Lite-Widgets' } +Package { #name : #'Material-Design-Lite-Widgets' }