Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
appId: swmansion.enriched.markdown.example
tags:
- block
- advanced
- list
- text
---
- launchApp:
permissions: {}

- waitForAnimationToEnd

- runFlow:
file: '../../../../subflows/move_to_playground.yaml'

- assertVisible:
id: playground-screen

- runFlow:
file: '../../../subflows/set_enriched_text_value.yaml'
env:
VALUE: |
1. First short item
2. Second short item
3. Third short item

- runFlow:
when:
platform: Android
commands:
- scrollUntilVisible:
element:
id: blur-button
direction: UP
visibilityPercentage: 100
- tapOn:
id: blur-button

- scrollUntilVisible:
element:
id: preview-container
direction: DOWN
visibilityPercentage: 100

- runFlow:
file: '../../../subflows/capture_or_assert_screenshot.yaml'
env:
SCREENSHOT_NAME: 'ordered_list_wide_markers_short_control_display'

- scrollUntilVisible:
element:
id: set-markdown-button
direction: UP
visibilityPercentage: 100

- runFlow:
file: '../../../subflows/set_enriched_text_value.yaml'
env:
VALUE: |
98. Before the boundary
99. Two-digit marker
100. Three-digit marker
101. After the boundary

- runFlow:
when:
platform: Android
commands:
- scrollUntilVisible:
element:
id: blur-button
direction: UP
visibilityPercentage: 100
- tapOn:
id: blur-button

- scrollUntilVisible:
element:
id: preview-container
direction: DOWN
visibilityPercentage: 100

- runFlow:
file: '../../../subflows/capture_or_assert_screenshot.yaml'
env:
SCREENSHOT_NAME: 'ordered_list_wide_markers_hundreds_display'

- scrollUntilVisible:
element:
id: set-markdown-button
direction: UP
visibilityPercentage: 100

- runFlow:
file: '../../../subflows/set_enriched_text_value.yaml'
env:
VALUE: |
998. Before the boundary
999. Three-digit marker
1000. Four-digit marker
1001. After the boundary

- runFlow:
when:
platform: Android
commands:
- scrollUntilVisible:
element:
id: blur-button
direction: UP
visibilityPercentage: 100
- tapOn:
id: blur-button

- scrollUntilVisible:
element:
id: preview-container
direction: DOWN
visibilityPercentage: 100

- runFlow:
file: '../../../subflows/capture_or_assert_screenshot.yaml'
env:
SCREENSHOT_NAME: 'ordered_list_wide_markers_thousands_display'

- scrollUntilVisible:
element:
id: set-markdown-button
direction: UP
visibilityPercentage: 100

- runFlow:
file: '../../../subflows/set_enriched_text_value.yaml'
env:
VALUE: |
1000. Wide parent
1. Nested first item
1. Deeper nested item
2. Nested second item
1001. Next wide parent

- runFlow:
when:
platform: Android
commands:
- scrollUntilVisible:
element:
id: blur-button
direction: UP
visibilityPercentage: 100
- tapOn:
id: blur-button

- scrollUntilVisible:
element:
id: preview-container
direction: DOWN
visibilityPercentage: 100

- runFlow:
file: '../../../subflows/capture_or_assert_screenshot.yaml'
env:
SCREENSHOT_NAME: 'ordered_list_wide_markers_nested_display'
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
appId: swmansion.enriched.markdown.ios.example
tags:
- block
- list
- text
---
- launchApp

- runFlow:
file: '../../../../subflows/move_to_playground.yaml'

- runFlow:
file: '../../../subflows/set_enriched_text_value.yaml'
env:
VALUE: |
1. One
2. Two
3. Three
4. Four
5. Five
6. Six
7. Seven
8. Eight
9. Nine
10. Ten
11. Eleven
12. Twelve
- Nested under a two-digit item

- runFlow:
file: '../../../subflows/capture_or_assert_screenshot.yaml'
env:
SCREENSHOT_NAME: 'ordered_list_wide_markers_display'
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/docs/android/api-reference/style-properties.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ Requires [`MarkdownOptions(admonitions = true)`](/android/api-reference/enriched
| `bulletSize` | `Dp` | `6.dp` | Unordered list bullet size |
| `markerColor` | `Color` | `#6B7280` | Ordered list number color |
| `markerFontWeight` | `FontWeight` | `FontWeight.Medium` (500) | Ordered list number weight |
| `markerMinWidth` | `Dp` | `0.dp` | Minimum width reserved for the marker column |
| `markerMinWidth` | `Dp` | `0.dp` | Minimum width reserved for the marker column. An ordered list's column also grows to fit its widest number |
| `gapWidth` | `Dp` | `12.dp` | Gap between the marker and the text |
| `marginLeft` | `Dp` | `24.dp` | Indent applied per nesting level |

Expand Down
2 changes: 1 addition & 1 deletion docs/docs/ios/api-reference/style-properties.md
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ Ordered and unordered lists, and their markers. Takes the [shared modifiers](#sh
| `.bulletColor(_:)` | `Color \| semantic` | `.secondary` | The dot drawn for an unordered item |
| `.bulletSize(_:)` | `CGFloat` | `6` | Diameter of that dot, in points |
| `.markerColor(_:)` | `Color \| semantic` | `.secondary` | The `1.` `2.` `3.` of an ordered item |
| `.markerMinWidth(_:)` | `CGFloat` | `0` | Minimum width reserved for the marker column, so numbers past `9.` do not shift the text. `0` sizes the column to each marker |
| `.markerMinWidth(_:)` | `CGFloat` | `0` | Minimum width reserved for the marker column. An ordered list's column also grows to fit its widest number, so its markers are never clipped |
| `.gapWidth(_:)` | `CGFloat` | `12` | Space between the marker and the item text. Clamped to a minimum of `4` |
| `.marginLeading(_:)` | `CGFloat` | `24` | Indent added per nesting level |

Expand Down
2 changes: 1 addition & 1 deletion docs/docs/react-native/api-reference/style-properties.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ Requires [`flavor="github"`](/react-native/api-reference/enriched-markdown-text#
| ------------------ | -------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `bulletColor` | `string` | `#6B7280` | Bullet point color |
| `bulletSize` | `number` | `6` | Bullet point size |
| `markerMinWidth` | `number` | `0` | Minimum reserved marker column width (floors the natural width of every list type) |
| `markerMinWidth` | `number` | `0` | Minimum reserved marker column width (floors the natural width of every list type). An ordered list's column also grows to fit its widest number |
| `markerColor` | `string` | `#6B7280` | Number marker color |
| `markerFontWeight` | `string` | `'500'` | Number marker font weight |
| `gapWidth` | `number` | `12` | Gap between marker and text |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ class BlockStyleContext {
var listDepth = 0
var listType: ListType? = null
var listItemNumber = 0
var listMarkerExtra = 0f
var ancestorMarkerOffset = 0f
var listItemMarkerExtra = 0f
var taskItemCount = 0

private val orderedListItemNumbers = ArrayDeque<Int>()
Expand Down Expand Up @@ -149,6 +152,9 @@ class BlockStyleContext {
listDepth = 0
listType = null
listItemNumber = 0
listMarkerExtra = 0f
ancestorMarkerOffset = 0f
listItemMarkerExtra = 0f
taskItemCount = 0
orderedListItemNumbers.clear()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import com.swmansion.enriched.markdown.styles.ListStyle
* allowing each level to maintain its own counter while preserving parent's position.
* - **Parent context restoration**: Restores parent list's style when exiting nested lists
* so subsequent parent items render correctly.
* - **Marker column**: An ordered list widens its `99.` column to fit its widest marker, and a
* nested list inherits the widening of the item it sits in.
*/
class ListContextManager(
private val context: BlockStyleContext,
Expand All @@ -24,6 +26,8 @@ class ListContextManager(
val previousDepth: Int,
val parentListType: BlockStyleContext.ListType?,
val wasNestedInOrderedList: Boolean,
val previousMarkerExtra: Float,
val previousMarkerOffset: Float,
)

/**
Expand All @@ -32,10 +36,12 @@ class ListContextManager(
* - Incrementing list depth
* - Setting the appropriate list style
* - Resetting item number for the new list
* - Widening the marker column by [markerExtraWidth] and shifting a nested list by its parent item's widening
*/
fun enterList(
listType: BlockStyleContext.ListType,
style: ListStyle,
markerExtraWidth: Float = 0f,
): ListEntryState {
val previousDepth = context.listDepth
val isNested = previousDepth > 0
Expand All @@ -60,10 +66,19 @@ class ListContextManager(
}
context.resetListItemNumber()

val previousMarkerExtra = context.listMarkerExtra
val previousMarkerOffset = context.ancestorMarkerOffset
if (isNested) {
context.ancestorMarkerOffset += context.listItemMarkerExtra
}
context.listMarkerExtra = markerExtraWidth

return ListEntryState(
previousDepth = previousDepth,
parentListType = parentListType,
wasNestedInOrderedList = isNested && parentIsOrdered,
previousMarkerExtra = previousMarkerExtra,
previousMarkerOffset = previousMarkerOffset,
)
}

Expand All @@ -73,6 +88,7 @@ class ListContextManager(
* - Decrementing list depth back to previousDepth
* - Restoring parent list item numbers from stack (if applicable)
* - Restoring parent list metadata (if nested) so subsequent parent items render correctly
* - Restoring the parent list's marker column and offset
*/
fun exitList(entryState: ListEntryState) {
context.listDepth = entryState.previousDepth
Expand All @@ -85,5 +101,8 @@ class ListContextManager(
if (entryState.previousDepth > 0) {
context.listType = entryState.parentListType
}

context.listMarkerExtra = entryState.previousMarkerExtra
context.ancestorMarkerOffset = entryState.previousMarkerOffset
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,8 @@ class ListItemRenderer(
// indices, matching the top-down order of `- [ ]` markers in the source.
val taskIndex = if (isTask) styleContext.taskItemCount++ else -1

factory.renderChildren(node, builder, onLinkPress, onLinkLongPress)

if (builder.length == start || builder.substring(start).isBlank()) return

while (builder.length > start && builder.last() == '\n') {
builder.delete(builder.length - 1, builder.length)
}
builder.append("\n")

val depth = styleContext.listDepth - 1
val listStyle = config.style.listStyle
val itemEnd = builder.length
val span =
if (isTask) {
TaskListSpan(
Expand All @@ -59,21 +49,53 @@ class ListItemRenderer(
styleCache = factory.styleCache,
taskIndex = taskIndex,
isChecked = isChecked,
ancestorMarkerOffset = styleContext.ancestorMarkerOffset,
markerExtraWidth = styleContext.listMarkerExtra,
)
} else {
when (listType) {
BlockStyleContext.ListType.UNORDERED -> {
UnorderedListSpan(listStyle, depth, factory.context, factory.styleCache)
UnorderedListSpan(
listStyle,
depth,
factory.context,
factory.styleCache,
ancestorMarkerOffset = styleContext.ancestorMarkerOffset,
)
}

BlockStyleContext.ListType.ORDERED -> {
OrderedListSpan(listStyle, depth, factory.context, factory.styleCache).apply {
OrderedListSpan(
listStyle,
depth,
factory.context,
factory.styleCache,
markerExtraWidth = styleContext.listMarkerExtra,
ancestorMarkerOffset = styleContext.ancestorMarkerOffset,
).apply {
setItemNumber(styleContext.listItemNumber)
}
}
}
}

// Nested lists inside this item shift by its extra marker width.
val previousMarkerExtra = styleContext.listItemMarkerExtra
styleContext.listItemMarkerExtra = span.markerExtraWidth
try {
factory.renderChildren(node, builder, onLinkPress, onLinkLongPress)
} finally {
styleContext.listItemMarkerExtra = previousMarkerExtra
}

if (builder.length == start || builder.substring(start).isBlank()) return

while (builder.length > start && builder.last() == '\n') {
builder.delete(builder.length - 1, builder.length)
}
builder.append("\n")

val itemEnd = builder.length
builder.setSpan(span, start, itemEnd, SPAN_FLAGS_LIST_ITEM)

if (isChecked) {
Expand Down
Loading
Loading